AudioRecord and FFT/MSE comparison. Call AudioRecord_demo for control record and AudioSample for subsequent recordings.

Dependencies:   CMSIS_DSP_401 STM32L4xx_HAL_Driver

Fork of OneHopeOnePrayer by Senior Design: Sound Monitor

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32l4xx_nucleo_audio.c Source File

stm32l4xx_nucleo_audio.c

Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_nucleo_audio.c
00004   * @author  MCD Application Team
00005   * @version V1.0.1
00006   * @date    16-September-2015
00007   * @brief   This file provides a set of functions needed to manage the 
00008   *          Audio driver for the STM32L476G-Nucleo board.
00009   ******************************************************************************
00010   * @attention
00011   *
00012   * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
00013   *
00014   * Redistribution and use in source and binary forms, with or without modification,
00015   * are permitted provided that the following conditions are met:
00016   *   1. Redistributions of source code must retain the above copyright notice,
00017   *      this list of conditions and the following disclaimer.
00018   *   2. Redistributions in binary form must reproduce the above copyright notice,
00019   *      this list of conditions and the following disclaimer in the documentation
00020   *      and/or other materials provided with the distribution.
00021   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00022   *      may be used to endorse or promote products derived from this software
00023   *      without specific prior written permission.
00024   *
00025   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00026   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00028   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00029   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00030   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00031   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00032   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00033   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00034   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035   *
00036   ******************************************************************************
00037   */
00038 
00039 /*==============================================================================
00040                                  User NOTES
00041                                  
00042 1. How To use this driver:
00043 --------------------------
00044    + This driver supports STM32L4xx devices on STM32L476G-Nucleo (MB1184) Nucleo boards.
00045         a) to play an audio file (all functions names start by BSP_AUDIO_OUT_xxx)
00046         b) to record an audio file through MP34DT01TR, ST MEMS (all functions names start by BSP_AUDIO_IN_xxx)
00047 
00048 a) PLAY A FILE:
00049 ==============
00050    + Call the function BSP_AUDIO_OUT_Init(
00051                                     OutputDevice: physical output mode (OUTPUT_DEVICE_SPEAKER, 
00052                                                   OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH)
00053                                     Volume      : Initial volume to be set (0 is min (mute), 100 is max (100%)
00054                                     AudioFreq   : Audio frequency in Hz (8000, 16000, 22500, 32000...)
00055                                                   this parameter is relative to the audio file/stream type.
00056                                    )
00057       This function configures all the hardware required for the audio application (codec, I2C, SAI, 
00058       GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if configuration is OK.
00059       If the returned value is different from AUDIO_OK or the function is stuck then the communication with
00060       the audio codec has failed.
00061       - OUTPUT_DEVICE_SPEAKER  : only speaker will be set as output for the audio stream.
00062       - OUTPUT_DEVICE_HEADPHONE: only headphones will be set as output for the audio stream.
00063       - OUTPUT_DEVICE_BOTH     : both Speaker and Headphone are used as outputs for the audio stream
00064                                  at the same time.
00065 
00066    + Call the function BSP_AUDIO_OUT_RegisterCallbacks to register user callbacks
00067      required to manage audio data streaming towards the audio codec (ErrorCallback(),
00068      HalfTransfer_CallBack() and TransferComplete_CallBack()).
00069 
00070    + Call the function BSP_AUDIO_OUT_Play() to start audio playback (for the first time).
00071    + Call the function BSP_AUDIO_OUT_Pause() to pause audio playabck   
00072    + Call the function BSP_AUDIO_OUT_Resume() to resume audio playback.
00073        Note. After calling BSP_AUDIO_OUT_Pause() function for pause, only BSP_AUDIO_OUT_Resume() should be called
00074           for resume (it is not allowed to call BSP_AUDIO_OUT_Play() in this case).
00075        Note. This function should be called only when the audio file is played or paused (not stopped).
00076    + Call the function BSP_AUDIO_OUT_Stop() to stop audio playback.
00077    + To modify the volume level, the sampling frequency, the device output mode, 
00078       the mute status or the audio configuration or the stop, use the functions: BSP_AUDIO_OUT_SetVolume(), 
00079       AUDIO_OUT_SetFrequency(), BSP_AUDIO_OUT_SetOutputMode(), BSP_AUDIO_OUT_SetMute()and 
00080       BSP_AUDIO_OUT_ChangeAudioConfig().
00081  
00082 Driver architecture:
00083 --------------------
00084    + This driver provides the audio layer high level API: it consists in functions
00085      exported in the stm32l4xx_nucleo_audio.h file (e.g. BSP_AUDIO_OUT_Init(),
00086      BSP_AUDIO_OUT_Play(), ...).
00087    + This driver also includes the Media Access Layer (MAL): it consists in 
00088      functions allowing to access setup the audio devices. These functions 
00089      are  included as local functions into the stm32l4xx_nucleo_audio.c file
00090      (e.g. AUDIO_SAIx_Init()).
00091 
00092 Known Limitations:
00093 ------------------
00094    1- Communication with the audio codec (through I2C) may be corrupted if it is interrupted by some
00095       user interrupt routines (in this case, interrupts could be disabled just before the start of 
00096       communication then re-enabled when it is over). Note that this communication is only done at
00097       the configuration phase (BSP_AUDIO_OUT_Init() or BSP_AUDIO_OUT_Stop()) and when Volume control modification is 
00098       performed (BSP_AUDIO_OUT_SetVolume() or BSP_AUDIO_OUT_SetMute()or BSP_AUDIO_OUT_SetOutputMode()). 
00099       When the audio data is played, no communication is required with the audio codec.
00100    2- Parsing of audio file is not implemented (in order to determine audio file properties: Mono/Stereo, Data size, 
00101       File size, Audio Frequency, Audio Data header size ...). The configuration is fixed for the given audio file.
00102    3- Supports only 16-bits audio data size.
00103 
00104 b) RECORD A FILE:
00105 ================
00106    + Call the function BSP_AUDIO_IN_Init(
00107                                     AudioFreq: Audio frequency in Hz (8000, 16000, 22500, 32000 ...)
00108                                     )
00109       This function configures all the hardware required for the audio application (DFSDM, 
00110       GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if the 
00111       configuration completes successfully.
00112 
00113    + Call the function BSP_AUDIO_IN_RegisterCallbacks to register user callbacks
00114      used to stream audio data toward the record buffer (ErrorCallback(),
00115      HalfTransfer_CallBack() and TransferComplete_CallBack()).
00116 
00117    + Call the function BSP_AUDIO_IN_Record(
00118                             pbuf Main buffer pointer for the recorded data storing  
00119                             size Current size of the recorded buffer
00120                             )
00121       to start recording from the microphone.
00122 
00123    + Call the function AUDIO_IN_STOP() to stop recording 
00124 ==============================================================================*/
00125 
00126 /* Includes ------------------------------------------------------------------*/
00127 #include <string.h>
00128 #include "stm32l4xx_nucleo_audio.h"
00129 
00130 /** @addtogroup BSP
00131   * @{
00132   */
00133 
00134 /** @addtogroup STM32L476G_NUCLEO
00135   * @{
00136   */
00137 
00138 /** @defgroup STM32L476G_NUCLEO_AUDIO STM32L476G-NUCLEO AUDIO
00139   * @brief This file includes the low layer driver for cs43l22 Audio Codec
00140   *        available on STM32L476G-Nucleo board(MB1184).
00141   * @{
00142   */ 
00143 
00144 /* Private typedef -----------------------------------------------------------*/
00145 /** @defgroup STM32L476G_NUCLEO_AUDIO_Private_Types Private Types
00146   * @{
00147   */
00148 //typedef struct
00149 //{
00150 //  AUDIO_DrvTypeDef *    AudioDrv;            /* Audio codec driver */
00151 //  Audio_CallbackTypeDef CbError;            /* pointer to the callback function invoked when ... */
00152 //  Audio_CallbackTypeDef CbHalfTransfer;     /* pointer to the callback function invoked when ... */
00153 //  Audio_CallbackTypeDef CbTransferComplete; /* pointer to the callback function invoked when ... */
00154 //} AUDIO_OUT_TypeDef;
00155 
00156 typedef struct
00157 {
00158   DFSDM_Channel_HandleTypeDef hDfsdmLeftChannel;  /* DFSDM channel handle used for left channel */
00159   DMA_HandleTypeDef           hDmaDfsdmLeft;      /* DMA handle used for DFSDM regular conversions on left channel */
00160   int32_t *                   LeftRecBuff;        /* Buffers for left samples */
00161   uint32_t                Frequency;        /* Record Frequency */
00162   uint32_t                BitResolution;    /* Record bit resolution */
00163   uint32_t                ChannelNbr;       /* Record Channel Number */
00164   uint16_t *              pRecBuf;          /* Pointer to record user buffer */
00165   uint32_t                RecSize;          /* Size to record in mono, double size to record in stereo */
00166   Audio_CallbackTypeDef       CbError;            /* pointer to the callback function invoked when a DMA transfer fails */
00167   Audio_CallbackTypeDef       CbHalfTransfer;     /* pointer to the callback function invoked when half of the DMA transfer is completed */
00168   Audio_CallbackTypeDef       CbTransferComplete; /* pointer to the callback function invoked when the DMA transfer is completed */
00169 } AUDIO_IN_TypeDef;
00170 
00171 /**
00172   * @}
00173   */
00174 
00175 /* Private defines ------------------------------------------------------------*/
00176 /** @defgroup STM32L476G_NUCLEO_AUDIO_Private_Constants Private Constants
00177   * @{
00178   */
00179 /**
00180   * @}
00181   */
00182 
00183 /* Private macros ------------------------------------------------------------*/
00184 /** @defgroup STM32L476G_NUCLEO_AUDIO_Private_Macros Private Macros
00185   * @{
00186   */
00187 /*### PLAY ###*/
00188 /* SCK(kHz) = SAI_CK_x/(SAIClockDivider*2*256) */
00189 #define SAIClockDivider(__FREQUENCY__) \
00190         (__FREQUENCY__ == AUDIO_FREQUENCY_8K)  ? 12 \
00191       : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 2 \
00192       : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 6 \
00193       : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 1 \
00194       : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 3 \
00195       : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 0 \
00196       : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 2 : 1  \
00197 
00198 /*### RECORD ###*/
00199 #define DFSDMOverSampling(__FREQUENCY__) \
00200         (__FREQUENCY__ == AUDIO_FREQUENCY_8K)  ? 256 \
00201       : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 256 \
00202       : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 128 \
00203       : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 128 \
00204       : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 64 \
00205       : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 64  \
00206       : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 32 : 16  \
00207 
00208 #define DFSDMClockDivider(__FREQUENCY__) \
00209         (__FREQUENCY__ == AUDIO_FREQUENCY_8K)  ? 24 \
00210       : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 4 \
00211       : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 24 \
00212       : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 4 \
00213       : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 24 \
00214       : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 4  \
00215       : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 32 : 32  \
00216 
00217 #define DFSDMFilterOrder(__FREQUENCY__) \
00218         (__FREQUENCY__ == AUDIO_FREQUENCY_8K)  ? DFSDM_FILTER_SINC3_ORDER \
00219       : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? DFSDM_FILTER_SINC3_ORDER \
00220       : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? DFSDM_FILTER_SINC3_ORDER \
00221       : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? DFSDM_FILTER_SINC3_ORDER \
00222       : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? DFSDM_FILTER_SINC4_ORDER \
00223       : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? DFSDM_FILTER_SINC4_ORDER  \
00224       : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? DFSDM_FILTER_SINC4_ORDER : DFSDM_FILTER_SINC5_ORDER  \
00225 
00226 #define DFSDMRightBitShift(__FREQUENCY__) \
00227         (__FREQUENCY__ == AUDIO_FREQUENCY_8K)  ? 2 \
00228       : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 3 \
00229       : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 3 \
00230       : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 0 \
00231       : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 3 \
00232       : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 3  \
00233       : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 7 : 0  \
00234 
00235 /* Saturate the record PCM sample */
00236 #define SaturaLH(N, L, H) (((N)<(L))?(L):(((N)>(H))?(H):(N)))
00237 
00238 /**
00239   * @}
00240   */ 
00241   
00242 /* Private variables ---------------------------------------------------------*/
00243 /** @defgroup STM32L476G_NUCLEO_AUDIO_Private_Variables Private Variables
00244   * @{
00245   */
00246 /* Audio output context information */
00247 //static AUDIO_OUT_TypeDef hAudioOut;
00248 
00249 /* Audio input context information */
00250 static AUDIO_IN_TypeDef hAudioIn;
00251 
00252 /* SAI DMA handle */
00253 static DMA_HandleTypeDef hDmaSai;
00254 /**
00255   * @}
00256   */
00257 
00258 /* Exported variables ---------------------------------------------------------*/
00259 /** @defgroup STM32L476G_NUCLEO_AUDIO_Exported_Variables Exported Variables
00260   * @{
00261   */
00262 /* SAIx handle */
00263 SAI_HandleTypeDef               BSP_AUDIO_hSai;
00264     
00265 /* DFSDM filter handle */
00266 DFSDM_Filter_HandleTypeDef      BSP_AUDIO_hDfsdmLeftFilter;
00267 /**
00268   * @}
00269   */
00270 
00271 /* Private function prototypes -----------------------------------------------*/
00272 /** @defgroup STM32L476G_NUCLEO_AUDIO_Private_Functions Private Functions
00273   * @{
00274   */
00275 //static void    AUDIO_CODEC_Reset(void);
00276 //static uint8_t AUDIO_SAIx_Init(uint32_t AudioFreq);
00277 //static uint8_t AUDIO_SAIx_DeInit(void);
00278 static uint8_t AUDIO_DFSDMx_Init(uint32_t AudioFreq);
00279 static uint8_t AUDIO_DFSDMx_DeInit(void);
00280 static uint8_t AUDIO_SAIPLLConfig(uint32_t AudioFreq);
00281 /**
00282   * @}
00283   */
00284 
00285 /* Exported functions --------------------------------------------------------*/
00286 /** @addtogroup STM32L476G_NUCLEO_AUDIO_Exported_Functions
00287   * @{
00288   */ 
00289 
00290 /**
00291   * @brief  Configures the audio codec related peripherals.
00292   * @param  OutputDevice: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
00293   *                       or OUTPUT_DEVICE_BOTH.
00294   * @param  Volume: Initial volume level (from 0 (Mute) to 100 (Max))
00295   * @param  AudioFreq: Audio frequency used to play the audio stream.ion.  
00296   * @retval BSP AUDIO status
00297   * @note   The SAI PLL input clock must be configure in the user application.
00298   *         The SAI PLL configuration done within this function assumes that
00299   *         the SAI PLL input clock runs at 8 MHz.
00300   */
00301 //uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, 
00302 //                           uint8_t Volume,
00303 //                           uint32_t AudioFreq)
00304 //{ 
00305 //  /* Initialize the audio output context */
00306 //  hAudioOut.AudioDrv           = &cs43l22_drv; 
00307 //  hAudioOut.CbError            = (Audio_CallbackTypeDef)NULL; 
00308 //  hAudioOut.CbHalfTransfer     = (Audio_CallbackTypeDef)NULL; 
00309 //  hAudioOut.CbTransferComplete = (Audio_CallbackTypeDef)NULL;
00310 //  
00311 //  /* Configure the SAI PLL according to the requested audio frequency */
00312 //  if (AUDIO_SAIPLLConfig(AudioFreq) != AUDIO_OK)
00313 //  {
00314 //    return AUDIO_ERROR;
00315 //  }
00316 //        
00317 //  /* SAI data transfer preparation: prepare the Media to be used for the audio
00318 //     transfer from memory to SAI peripheral. */
00319 //  if (AUDIO_SAIx_Init(AudioFreq) != AUDIO_OK)
00320 //  {
00321 //    return AUDIO_ERROR;
00322 //  }
00323 //
00324 //  /* Retieve audio codec identifier */
00325 //  if (cs43l22_drv.ReadID(AUDIO_I2C_ADDRESS) != CS43L22_ID)
00326 //  {
00327 //    return AUDIO_ERROR;
00328 //  }
00329 //  
00330 //  /* Reset the audio codec Registers */
00331 //  AUDIO_CODEC_Reset();
00332 //  
00333 //  /* Initialize the audio codec internal registers */
00334 //  if (hAudioOut.AudioDrv->Init(AUDIO_I2C_ADDRESS, 
00335 //                               OutputDevice, 
00336 //                               Volume, 
00337 //                               AudioFreq) != 0)
00338 //  {
00339 //    return AUDIO_ERROR;
00340 //  }
00341 //  
00342 //  /* Set the requested volume */
00343 //  BSP_AUDIO_OUT_SetVolume(Volume);
00344 //
00345 //  return AUDIO_OK;
00346 //}
00347   
00348 /**
00349   * @brief  De-Initializes audio codec related peripherals
00350   * @retval BSP AUDIO status
00351   
00352   */
00353 //uint8_t BSP_AUDIO_OUT_DeInit(void)
00354 //{
00355 //  /* De-initializes the Audio Codec audio interface */
00356 //  if (AUDIO_SAIx_DeInit() != AUDIO_OK)
00357 //  {  
00358 //    return AUDIO_ERROR;
00359 //  }
00360 //
00361 //  /* DeInit Audio component interface */
00362 //  hAudioOut.AudioDrv->DeInit();
00363 //  
00364 //  return AUDIO_OK;
00365 //}
00366 
00367 /**
00368   * @brief  Starts playing audio stream from a data buffer for a determined size. 
00369   * @param  pData: pointer on PCM samples buffer 
00370   * @param  Size: Number of audio data BYTES.
00371   * @retval BSP AUDIO status
00372   */
00373 //uint8_t BSP_AUDIO_OUT_Play(uint16_t* pData, uint32_t Size)
00374 //{
00375 //  /* Initiate a DMA transfer of PCM samples towards the serial audio interface */  
00376 //  if (HAL_SAI_Transmit_DMA(&BSP_AUDIO_hSai, (uint8_t *)pData, DMA_MAX(Size))!= HAL_OK)
00377 //  {
00378 //    return AUDIO_ERROR;
00379 //  }
00380 //
00381 //  /* Call the audio Codec Play function */
00382 //  if (hAudioOut.AudioDrv->Play(AUDIO_I2C_ADDRESS, pData, Size) != 0)
00383 //  {  
00384 //    return AUDIO_ERROR;
00385 //  }
00386 //
00387 //  return AUDIO_OK;
00388 //  }
00389 
00390 /**
00391   * @brief  Sends n-Bytes on the SAI interface.
00392   * @param  pData: pointer on PCM samples buffer 
00393   * @param  Size: number of data to be written
00394   * @retval BSP AUDIO status
00395   */
00396 //uint8_t BSP_AUDIO_OUT_ChangeBuffer(uint16_t *pData, uint16_t Size)
00397 //{
00398 //  /* Initiate a DMA transfer of PCM samples towards the serial audio interface */  
00399 //  if (HAL_SAI_Transmit_DMA(&BSP_AUDIO_hSai, (uint8_t *)pData, Size)!= HAL_OK)
00400 //  {
00401 //    return AUDIO_ERROR;
00402 //  }
00403 //  
00404 //  return AUDIO_OK;
00405 //}
00406 
00407 /**
00408   * @brief  This function Pauses the audio file stream. In case
00409   *         of using DMA, the DMA Pause feature is used.
00410   * @note When calling BSP_AUDIO_OUT_Pause() function for pause, only
00411   *       BSP_AUDIO_OUT_Resume() function should be called for resume
00412   *       (use of BSP_AUDIO_OUT_Play() function for resume could lead 
00413   *       to unexpected behavior).
00414   * @retval BSP AUDIO status
00415   */
00416 //uint8_t BSP_AUDIO_OUT_Pause(void)
00417 //{
00418 //  /* Call the Audio Codec Pause function */
00419 //  if (hAudioOut.AudioDrv->Pause(AUDIO_I2C_ADDRESS) != 0)
00420 //  {
00421 //    return AUDIO_ERROR;
00422 //  }
00423 //  
00424 //  /* Pause DMA transfer of PCM samples towards the serial audio interface */  
00425 //  if (HAL_SAI_DMAPause(&BSP_AUDIO_hSai)!= HAL_OK)
00426 //  {
00427 //    return AUDIO_ERROR;
00428 //  }
00429 //  
00430 //  return AUDIO_OK;
00431 //}
00432 
00433 /**
00434   * @brief  This function  Resumes the audio file stream.  
00435   * @note When calling BSP_AUDIO_OUT_Pause() function for pause, only
00436   *       BSP_AUDIO_OUT_Resume() function should be called for resume
00437   *       (use of BSP_AUDIO_OUT_Play() function for resume could lead to 
00438   *       unexpected behavior).
00439   * @retval BSP AUDIO status
00440   */
00441 //uint8_t BSP_AUDIO_OUT_Resume(void)
00442 //{    
00443 //  /* Call the Audio Codec Resume function */
00444 //  if (hAudioOut.AudioDrv->Resume(AUDIO_I2C_ADDRESS) != 0)
00445 //  {
00446 //    return AUDIO_ERROR;
00447 //  }
00448 //
00449 //  /* Resume DMA transfer of PCM samples towards the serial audio interface */  
00450 //  if (HAL_SAI_DMAResume(&BSP_AUDIO_hSai)!= HAL_OK)
00451 //  {
00452 //    return AUDIO_ERROR;
00453 //  }
00454 //  
00455 //  return AUDIO_OK;
00456 //}
00457 
00458 /**
00459   * @brief  Stops audio playing and Power down the Audio Codec. 
00460   * @param  Option: could be one of the following parameters 
00461   *           - CODEC_PDWN_SW: for software power off (by writing registers). 
00462   *                            Then no need to reconfigure the Codec after power on.
00463   *           - CODEC_PDWN_HW: completely shut down the codec (physically). 
00464   *                            Then need to reconfigure the Codec after power on.  
00465   * @retval BSP AUDIO status
00466   */
00467 //uint8_t BSP_AUDIO_OUT_Stop(uint32_t Option)
00468 //{
00469 //  /* Call Audio Codec Stop function */
00470 //  if (hAudioOut.AudioDrv->Stop(AUDIO_I2C_ADDRESS, Option) != 0)
00471 //  {
00472 //    return AUDIO_ERROR;
00473 //  }
00474 //  
00475 //  if(Option == CODEC_PDWN_HW)
00476 //  { 
00477 //    /* Wait at least 100us */
00478 //    HAL_Delay(1);
00479 //  }
00480 //
00481 //  /* Stop DMA transfer of PCM samples towards the serial audio interface */  
00482 //  if (HAL_SAI_DMAStop(&BSP_AUDIO_hSai)!= HAL_OK)
00483 //  {
00484 //    return AUDIO_ERROR;
00485 //  }
00486 //  
00487 //  return AUDIO_OK;
00488 //}
00489 
00490 /**
00491   * @brief  Controls the current audio volume level. 
00492   * @param  Volume: Volume level to be set in percentage from 0% to 100% (0 for 
00493   *         Mute and 100 for Max volume level).
00494   * @retval BSP AUDIO status
00495   */
00496 //uint8_t BSP_AUDIO_OUT_SetVolume(uint8_t Volume)
00497 //{
00498 //  /* Call the codec volume control function with converted volume value */
00499 //  if (hAudioOut.AudioDrv->SetVolume(AUDIO_I2C_ADDRESS, Volume) != 0)
00500 //  {
00501 //    return AUDIO_ERROR;
00502 //  }
00503 //  
00504 //  return AUDIO_OK;
00505 //}
00506 
00507 /**
00508   * @brief  Enables or disables the MUTE mode by software 
00509   * @param  Cmd: Could be AUDIO_MUTE_ON to mute sound or AUDIO_MUTE_OFF to 
00510   *         unmute the codec and restore previous volume level.
00511   * @retval BSP AUDIO status
00512   */
00513 //uint8_t BSP_AUDIO_OUT_SetMute(uint32_t Cmd)
00514 //{ 
00515 //  /* Call the Codec Mute function */
00516 //  if (hAudioOut.AudioDrv->SetMute(AUDIO_I2C_ADDRESS, Cmd) != 0)
00517 //  {
00518 //    return AUDIO_ERROR;
00519 //  }
00520 //  
00521 //  return AUDIO_OK;
00522 //}
00523 
00524 /**
00525   * @brief  Switch dynamically (while audio file is being played) the output 
00526   *          target (speaker or headphone).
00527   * @param  Output: The audio output target: OUTPUT_DEVICE_SPEAKER,
00528   *         OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH
00529   * @retval BSP AUDIO status
00530   */
00531 //uint8_t BSP_AUDIO_OUT_SetOutputMode(uint8_t Output)
00532 //{
00533 //  /* Call the Codec output device function */
00534 //  if (hAudioOut.AudioDrv->SetOutputMode(AUDIO_I2C_ADDRESS, Output) != 0)
00535 //  {
00536 //    return AUDIO_ERROR;
00537 //  }
00538 //  
00539 //  return AUDIO_OK;
00540 //}
00541 
00542 /**
00543   * @brief  Updates the audio frequency.
00544   * @param  AudioFreq: Audio frequency used to play the audio stream.
00545   * @note   The SAI PLL input clock must be configure in the user application.
00546   *         The SAI PLL configuration done within this function assumes that
00547   *         the SAI PLL input clock runs at 8 MHz.
00548   * @retval BSP AUDIO status
00549   */
00550 //uint8_t BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq)
00551 //{ 
00552 //  /* Configure the SAI PLL according to the requested audio frequency */
00553 //  if (AUDIO_SAIPLLConfig(AudioFreq) != AUDIO_OK)
00554 //  {
00555 //    return AUDIO_ERROR;
00556 //  }
00557 //  
00558 //  /* Disable SAI peripheral to allow access to SAI internal registers */
00559 //  __HAL_SAI_DISABLE(&BSP_AUDIO_hSai);
00560 //  
00561 //  /* Update the SAI audio frequency configuration */
00562 //  BSP_AUDIO_hSai.Init.Mckdiv = SAIClockDivider(AudioFreq);
00563 //  HAL_SAI_Init(&BSP_AUDIO_hSai);
00564 //  
00565 //  /* Enable SAI peripheral to generate MCLK */
00566 //  __HAL_SAI_ENABLE(&BSP_AUDIO_hSai);
00567 //
00568 //  return AUDIO_OK;
00569 //}
00570 
00571 /**
00572   * @brief  Changes the Audio Out Configuration.
00573   * @param  AudioOutOption: specifies the audio out new configuration
00574   *         This parameter can be any value of @ref BSP_Audio_Out_Option
00575   * @note   This API should be called after the BSP_AUDIO_OUT_Init() to adjust the
00576   *         audio out configuration.
00577   * @retval None
00578   */
00579 //void BSP_AUDIO_OUT_ChangeAudioConfig(uint32_t AudioOutOption)
00580 //{ 
00581 //  /********** Playback Buffer circular/normal mode **********/
00582 //  if(AudioOutOption & BSP_AUDIO_OUT_CIRCULARMODE)
00583 //  {
00584 //    /* Deinitialize the Stream to update DMA mode */
00585 //    HAL_DMA_DeInit(BSP_AUDIO_hSai.hdmatx);
00586 //    
00587 //    /* Update the SAI audio Transfer DMA mode */
00588 //    BSP_AUDIO_hSai.hdmatx->Init.Mode = DMA_CIRCULAR;
00589 //    
00590 //    /* Configure the DMA Stream with new Transfer DMA mode */
00591 //    HAL_DMA_Init(BSP_AUDIO_hSai.hdmatx);      
00592 //  }
00593 //  else /* BSP_AUDIO_OUT_NORMALMODE */
00594 //  {
00595 //    /* Deinitialize the Stream to update DMA mode */
00596 //    HAL_DMA_DeInit(BSP_AUDIO_hSai.hdmatx);
00597 //    
00598 //    /* Update the SAI audio Transfer DMA mode */
00599 //    BSP_AUDIO_hSai.hdmatx->Init.Mode = DMA_NORMAL;
00600 //    
00601 //    /* Configure the DMA Stream with new Transfer DMA mode */
00602 //    HAL_DMA_Init(BSP_AUDIO_hSai.hdmatx);      
00603 //  }
00604 //  
00605 //  /********** Playback Buffer stereo/mono mode **********/
00606 //  if(AudioOutOption & BSP_AUDIO_OUT_STEREOMODE)
00607 //  {
00608 //    /* Disable SAI peripheral to allow access to SAI internal registers */
00609 //    __HAL_SAI_DISABLE(&BSP_AUDIO_hSai);
00610 //    
00611 //    /* Update the SAI audio frame slot configuration */
00612 //    BSP_AUDIO_hSai.Init.MonoStereoMode = SAI_STEREOMODE;
00613 //    HAL_SAI_Init(&BSP_AUDIO_hSai);
00614 //    
00615 //    /* Enable SAI peripheral to generate MCLK */
00616 //    __HAL_SAI_ENABLE(&BSP_AUDIO_hSai);
00617 //  }
00618 //  else /* BSP_AUDIO_OUT_MONOMODE */
00619 //  {
00620 //    /* Disable SAI peripheral to allow access to SAI internal registers */
00621 //    __HAL_SAI_DISABLE(&BSP_AUDIO_hSai);
00622 //    
00623 //    /* Update the SAI audio frame slot configuration */
00624 //    BSP_AUDIO_hSai.Init.MonoStereoMode = SAI_MONOMODE;
00625 //    HAL_SAI_Init(&BSP_AUDIO_hSai);
00626 //    
00627 //    /* Enable SAI peripheral to generate MCLK */
00628 //    __HAL_SAI_ENABLE(&BSP_AUDIO_hSai);
00629 //  }
00630 //}
00631 
00632 /**
00633   * @brief  register user callback functions 
00634   * @param  ErrorCallback: pointer to the error callback function
00635   * @param  HalfTransferCallback: pointer to the half transfer callback function
00636   * @param  TransferCompleteCallback: pointer to the transfer complete callback function
00637   * @retval None
00638   */
00639 //void BSP_AUDIO_OUT_RegisterCallbacks(Audio_CallbackTypeDef ErrorCallback,
00640 //                                     Audio_CallbackTypeDef HalfTransferCallback, 
00641 //                                     Audio_CallbackTypeDef TransferCompleteCallback)
00642 //{
00643 //  hAudioOut.CbError            = ErrorCallback; 
00644 //  hAudioOut.CbHalfTransfer     = HalfTransferCallback; 
00645 //  hAudioOut.CbTransferComplete = TransferCompleteCallback;
00646 //}
00647 
00648 /**
00649   * @brief  Tx Transfer completed callbacks.
00650   * @param  hsai: SAI handle
00651   * @retval None
00652   */
00653 //void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
00654 //{
00655 //  /* Invoke the registered 'TransferComplete' function (if any) */
00656 //  if (hAudioOut.CbTransferComplete != (Audio_CallbackTypeDef)NULL)
00657 //  {
00658 //    hAudioOut.CbTransferComplete();
00659 //  }
00660 //}
00661 
00662 /**
00663   * @brief  Tx Half Transfer completed callbacks.
00664   * @param  hsai: SAI handle
00665   * @retval None
00666   */
00667 //void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
00668 //{
00669 //  /* Invoke the registered 'HalfTransfer' callback function (if any) */
00670 //  if (hAudioOut.CbHalfTransfer != (Audio_CallbackTypeDef)NULL)
00671 //  {
00672 //    hAudioOut.CbHalfTransfer();
00673 //  }
00674 //}
00675 
00676 /**
00677   * @brief  SAI error callbacks.
00678   * @param  hsai: SAI handle
00679   * @retval None
00680   */
00681 //void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai)
00682 //{
00683 //  /* Invoke the registered 'ErrorCallback' callback function (if any) */
00684 //  if (hAudioOut.CbError != (Audio_CallbackTypeDef)NULL)
00685 //  {
00686 //    hAudioOut.CbError();
00687 //  }
00688 //}
00689 
00690 /**
00691   * @}
00692   */
00693 
00694 /** @addtogroup STM32L476G_EVAL_AUDIO_Exported_Functions
00695   * @{
00696   */
00697   
00698 /**
00699   * @brief  Initializes micropone related peripherals.
00700   * @note   This function assumes that the SAI input clock (through PLL_M)
00701   *         is already configured and ready to be used.  
00702   * @param  AudioFreq: Audio frequency to be configured for the SAI peripheral. 
00703   * @param  BitRes: Audio frequency to be configured for the SAI peripheral.
00704   * @param  ChnlNbr: Audio frequency to be configured for the SAI peripheral.
00705   * @retval BSP AUDIO status
00706   */
00707 uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
00708 {
00709   /* Update the audio input context */
00710   hAudioIn.Frequency          = AudioFreq;
00711   hAudioIn.BitResolution      = BitRes;
00712   hAudioIn.ChannelNbr         = ChnlNbr;
00713   hAudioIn.CbError            = (Audio_CallbackTypeDef)NULL; 
00714   hAudioIn.CbHalfTransfer     = (Audio_CallbackTypeDef)NULL; 
00715   hAudioIn.CbTransferComplete = (Audio_CallbackTypeDef)NULL;
00716 
00717   /* Configure the SAI PLL according to the requested audio frequency */
00718   if (AUDIO_SAIPLLConfig(AudioFreq) != AUDIO_OK)
00719   {
00720     return AUDIO_ERROR;
00721   }
00722  
00723   /* Initializes the Digital Filter for Sigma-Delta Modulators interface */
00724   if(AUDIO_DFSDMx_Init(AudioFreq) != AUDIO_OK)
00725   {
00726     return AUDIO_ERROR;
00727   }
00728   
00729   return AUDIO_OK;
00730   }
00731 
00732 /**
00733   * @brief  De-Initializes microphone related peripherals.
00734   * @retval BSP AUDIO status
00735 
00736   */
00737 uint8_t BSP_AUDIO_IN_DeInit(void)
00738 {
00739   /* De-initializes the Digital Filter for Sigma-Delta Modulators interface */
00740   if (AUDIO_DFSDMx_DeInit() != AUDIO_OK)
00741   {
00742     return AUDIO_ERROR;
00743   }
00744   
00745   /* Reset the audio input context */
00746   memset(&hAudioIn, 0, sizeof(hAudioIn));
00747 
00748   return AUDIO_OK;
00749 }
00750 
00751 /**
00752   * @brief  Starts audio recording.
00753   * @param  pbuf: Main buffer pointer for the recorded data storing  
00754   * @param  size: Current size of the recorded buffer
00755   * @note   The Right channel is start at first with synchro on start of Left channel
00756   * @retval BSP AUDIO status
00757   */
00758 uint8_t BSP_AUDIO_IN_Record(uint16_t* pbuf, uint32_t size)
00759 {
00760   hAudioIn.pRecBuf = pbuf;
00761   hAudioIn.RecSize = size;
00762 
00763   /* Allocate hAudioIn.LeftRecBuff buffer */
00764 #if defined(BSP_AUDIO_USE_RTOS)
00765   hAudioIn.LeftRecBuff  = (int32_t *)k_malloc(size * sizeof(int32_t));
00766 #else
00767   hAudioIn.LeftRecBuff  = (int32_t *)malloc(size * sizeof(int32_t));
00768 #endif
00769   if(hAudioIn.LeftRecBuff == NULL)
00770   {
00771     return AUDIO_ERROR;
00772   }
00773 
00774   /* Call the Media layer start function for left channel */
00775   if(HAL_DFSDM_FilterRegularStart_DMA(&BSP_AUDIO_hDfsdmLeftFilter, 
00776                                       (int32_t*)hAudioIn.LeftRecBuff, 
00777                                       (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR)) != HAL_OK)
00778   {
00779     return AUDIO_ERROR;
00780   }
00781 
00782   return AUDIO_OK;
00783 }
00784 
00785 /**
00786   * @brief  Updates the audio frequency.
00787   * @param  AudioFreq: Audio frequency used to record the audio stream.
00788   * @note   This API should be called after the BSP_AUDIO_IN_Init() to adjust the
00789   *         audio frequency.
00790   * @retval BSP AUDIO status
00791   */
00792 uint8_t BSP_AUDIO_IN_SetFrequency(uint32_t AudioFreq)
00793 { 
00794   /* Configure the SAI PLL according to the requested audio frequency */
00795   if (AUDIO_SAIPLLConfig(AudioFreq) != AUDIO_OK)
00796   {
00797     return AUDIO_ERROR;
00798   }
00799 
00800   /* De-initializes the Digital Filter for Sigma-Delta Modulators interface */
00801   if(AUDIO_DFSDMx_DeInit() != AUDIO_OK)
00802   {
00803     return AUDIO_ERROR;
00804   }
00805   
00806   /* Initializes the Digital Filter for Sigma-Delta Modulators interface */
00807   if(AUDIO_DFSDMx_Init(AudioFreq) != AUDIO_OK)
00808   {
00809     return AUDIO_ERROR;
00810   }
00811   
00812   return AUDIO_OK;
00813 }
00814 
00815 /**
00816   * @brief  Regular conversion complete callback. 
00817   * @note   In interrupt mode, user has to read conversion value in this function
00818             using HAL_DFSDM_FilterGetRegularValue.
00819   * @param  hdfsdm_filter : DFSDM filter handle.
00820   * @retval None
00821   */
00822 void HAL_DFSDM_FilterRegConvCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
00823 {
00824   uint32_t index;
00825   uint32_t recbufsize = (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR);
00826   
00827   for(index = (recbufsize/2); index < recbufsize; index++)
00828   {
00829     hAudioIn.pRecBuf[index] = (uint16_t)(SaturaLH((hAudioIn.LeftRecBuff[index] >> 8), -32760, 32760));
00830   }
00831   
00832   /* Invoke the registered 'TransferComplete' function (if any) */
00833   if (hAudioIn.CbTransferComplete != (Audio_CallbackTypeDef)NULL)
00834   {
00835     hAudioIn.CbTransferComplete();
00836   }
00837 }
00838 
00839 /**
00840   * @brief  Half regular conversion complete callback. 
00841   * @param  hdfsdm_filter : DFSDM filter handle.
00842   * @retval None
00843   */
00844 void HAL_DFSDM_FilterRegConvHalfCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
00845 {
00846   uint32_t index;
00847   uint32_t recbufsize = (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR);
00848   
00849   
00850   for(index = 0; index < (recbufsize/2); index++)
00851   {
00852     hAudioIn.pRecBuf[index] = (uint16_t)(SaturaLH((hAudioIn.LeftRecBuff[index] >> 8), -32760, 32760));
00853   }
00854   
00855   /* Invoke the registered 'HalfTransfer' callback function (if any) */
00856   if (hAudioIn.CbHalfTransfer != (Audio_CallbackTypeDef)NULL)
00857   {
00858     hAudioIn.CbHalfTransfer();
00859   }
00860 }
00861 
00862 /**
00863   * @brief  Error callback. 
00864   * @param  hdfsdm_filter : DFSDM filter handle.
00865   * @retval None
00866   */
00867 void HAL_DFSDM_FilterErrorCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
00868 {
00869   /* Invoke the registered 'ErrorCallback' callback function (if any) */
00870   if (hAudioIn.CbError != (Audio_CallbackTypeDef)NULL)
00871   {
00872     hAudioIn.CbError();
00873   }
00874 }
00875 
00876 /**
00877   * @brief  Stops audio recording.
00878   * @retval BSP AUDIO status
00879   */
00880 uint8_t BSP_AUDIO_IN_Stop(void)
00881 {
00882   /* Call the Media layer stop function for left channel */
00883   if(HAL_DFSDM_FilterRegularStop_DMA(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK )
00884   {
00885     return AUDIO_ERROR;
00886   }
00887 
00888   /* Free hAudioIn.LeftRecBuff buffer */
00889 #if defined(BSP_AUDIO_USE_RTOS)
00890   k_free((void *)hAudioIn.LeftRecBuff);
00891 #else
00892   free((void *)hAudioIn.LeftRecBuff);
00893 #endif
00894   
00895   return AUDIO_OK;
00896 }
00897 
00898 /**
00899   * @brief  Pauses the audio file stream.
00900   * @retval BSP AUDIO status
00901   */
00902 uint8_t BSP_AUDIO_IN_Pause(void)
00903 {    
00904   /* Call the Media layer stop function */
00905   if(HAL_DFSDM_FilterRegularStop_DMA(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK)
00906   {
00907     return AUDIO_ERROR;
00908   }
00909   
00910   return AUDIO_OK;
00911 }
00912 
00913 /**
00914   * @brief  Resumes the audio file stream.
00915   * @retval BSP AUDIO status
00916   */
00917 uint8_t BSP_AUDIO_IN_Resume(void)
00918 {    
00919   /* Call the Media layer start function for left channel */
00920   if(HAL_DFSDM_FilterRegularStart_DMA(&BSP_AUDIO_hDfsdmLeftFilter,
00921                                       (int32_t*)hAudioIn.LeftRecBuff,
00922                                       (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR)) != HAL_OK)
00923   {
00924     return AUDIO_ERROR;
00925   }
00926   
00927   return AUDIO_OK;
00928 }
00929 
00930 /**
00931   * @brief  register user callback functions 
00932   * @param  ErrorCallback: pointer to the error callback function
00933   * @param  HalfTransferCallback: pointer to the half transfer callback function
00934   * @param  TransferCompleteCallback: pointer to the transfer complete callback function
00935   * @retval None
00936   */
00937 void BSP_AUDIO_IN_RegisterCallbacks(Audio_CallbackTypeDef ErrorCallback,
00938                                     Audio_CallbackTypeDef HalfTransferCallback, 
00939                                     Audio_CallbackTypeDef TransferCompleteCallback)
00940 {
00941   hAudioIn.CbError            = ErrorCallback; 
00942   hAudioIn.CbHalfTransfer     = HalfTransferCallback; 
00943   hAudioIn.CbTransferComplete = TransferCompleteCallback;
00944 }
00945 /**
00946   * @}
00947   */
00948 
00949 /* private functions --------------------------------------------------------*/
00950 /** @addtogroup STM32L476G_NUCLEO_AUDIO_Private_Functions
00951   * @{
00952   */
00953 /**
00954   * @brief  Initializes the Audio Codec audio interface (SAI).
00955   * @param  AudioFreq: Audio frequency to be configured for the SAI peripheral.
00956   * @note   The default SlotActive configuration is set to CODEC_AUDIOFRAME_SLOT_0123 
00957   *         and user can update this configuration using 
00958   * @retval BSP AUDIO status
00959   */
00960 //static uint8_t AUDIO_SAIx_Init(uint32_t AudioFreq)
00961 //{
00962 //  /* Disable SAI peripheral to allow access to SAI internal registers */
00963 //  __HAL_SAI_DISABLE(&BSP_AUDIO_hSai);
00964 //  
00965 //  /* Initialize the BSP_AUDIO_hSai Instance parameter */
00966 //  BSP_AUDIO_hSai.Instance = AUDIO_SAIx;
00967 //  
00968 //  /* Configure SAI_Block_x 
00969 //  LSBFirst: Disabled 
00970 //  DataSize: 16 */
00971 //  BSP_AUDIO_hSai.Init.AudioMode      = SAI_MODEMASTER_TX;
00972 //  BSP_AUDIO_hSai.Init.Synchro        = SAI_ASYNCHRONOUS;
00973 //  BSP_AUDIO_hSai.Init.SynchroExt     = SAI_SYNCEXT_DISABLE;
00974 //  BSP_AUDIO_hSai.Init.OutputDrive    = SAI_OUTPUTDRIVE_ENABLE;
00975 //  BSP_AUDIO_hSai.Init.NoDivider      = SAI_MASTERDIVIDER_ENABLE;
00976 //  BSP_AUDIO_hSai.Init.FIFOThreshold  = SAI_FIFOTHRESHOLD_1QF;
00977 //  BSP_AUDIO_hSai.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_MCKDIV;
00978 //  BSP_AUDIO_hSai.Init.Mckdiv         = SAIClockDivider(AudioFreq);
00979 //  BSP_AUDIO_hSai.Init.MonoStereoMode = SAI_STEREOMODE;
00980 //  BSP_AUDIO_hSai.Init.CompandingMode = SAI_NOCOMPANDING;
00981 //  BSP_AUDIO_hSai.Init.TriState       = SAI_OUTPUT_NOTRELEASED;
00982 //  BSP_AUDIO_hSai.Init.Protocol       = SAI_FREE_PROTOCOL;
00983 //  BSP_AUDIO_hSai.Init.DataSize       = SAI_DATASIZE_16;
00984 //  BSP_AUDIO_hSai.Init.FirstBit       = SAI_FIRSTBIT_MSB;
00985 //  BSP_AUDIO_hSai.Init.ClockStrobing  = SAI_CLOCKSTROBING_RISINGEDGE;
00986 //  
00987 //  /* Configure SAI_Block_x Frame 
00988 //  Frame Length: 32
00989 //  Frame active Length: 16
00990 //  FS Definition: Start frame + Channel Side identification
00991 //  FS Polarity: FS active Low
00992 //  FS Offset: FS asserted one bit before the first bit of slot 0 */ 
00993 //  BSP_AUDIO_hSai.FrameInit.FrameLength = 32;
00994 //  BSP_AUDIO_hSai.FrameInit.ActiveFrameLength = 16;
00995 //  BSP_AUDIO_hSai.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
00996 //  BSP_AUDIO_hSai.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
00997 //  BSP_AUDIO_hSai.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
00998 //  
00999 //  /* Configure SAI Block_x Slot 
01000 //  Slot First Bit Offset: 0
01001 //  Slot Size  : 16
01002 //  Slot Number: 2
01003 //  Slot Active: Slots 0 and 1 actives */
01004 //  BSP_AUDIO_hSai.SlotInit.FirstBitOffset = 0;
01005 //  BSP_AUDIO_hSai.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
01006 //  BSP_AUDIO_hSai.SlotInit.SlotNumber = 2; 
01007 //  BSP_AUDIO_hSai.SlotInit.SlotActive = SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1;
01008 //
01009 //  /* Initializes the SAI peripheral*/
01010 //  if (HAL_SAI_Init(&BSP_AUDIO_hSai) != HAL_OK)
01011 //  {
01012 //    return AUDIO_ERROR;
01013 //  }
01014 //  
01015 //  /* Enable SAI peripheral to generate MCLK */
01016 //  __HAL_SAI_ENABLE(&BSP_AUDIO_hSai);
01017 //  
01018 //  return AUDIO_OK;
01019 //  
01020 //}
01021 
01022 /**
01023   * @brief  De-initializes the Audio Codec audio interface (SAI).
01024   * @retval BSP AUDIO status
01025   */
01026 //static uint8_t AUDIO_SAIx_DeInit(void)
01027 //{
01028 //  /* Disable the SAI audio block */
01029 //  __HAL_SAI_DISABLE(&BSP_AUDIO_hSai);
01030 //
01031 //  /* De-initializes the SAI peripheral */
01032 //  if (HAL_SAI_DeInit(&BSP_AUDIO_hSai) != HAL_OK)
01033 //  {
01034 //    return AUDIO_ERROR;
01035 //  }
01036 //  
01037 //  /* Disable SAIx PLL */
01038 //  if (AUDIO_SAIx_PLL_DISABLE() != AUDIO_OK)
01039 //  {
01040 //    return AUDIO_ERROR;
01041 //  }  
01042 //  
01043 //  return AUDIO_OK;
01044 //}
01045 
01046 /**
01047   * @brief  SAI MSP Init
01048   * @param  hsai : pointer to a SAI_HandleTypeDef structure
01049   * @retval None
01050   */
01051 void HAL_SAI_MspInit(SAI_HandleTypeDef *hsai)
01052 { 
01053   GPIO_InitTypeDef  GPIO_InitStruct;  
01054 
01055   /* Enable SAI clock */
01056   AUDIO_SAIx_CLK_ENABLE();
01057   
01058   /* Enable GPIO clock */
01059   AUDIO_SAIx_MCK_SCK_SD_FS_ENABLE();
01060   
01061   /* CODEC_SAI pins configuration: FS, SCK, MCK and SD pins ------------------*/
01062   GPIO_InitStruct.Pin = AUDIO_SAIx_FS_PIN | AUDIO_SAIx_SCK_PIN | AUDIO_SAIx_SD_PIN | AUDIO_SAIx_MCK_PIN;
01063   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
01064   GPIO_InitStruct.Pull = GPIO_NOPULL;
01065   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
01066   GPIO_InitStruct.Alternate = AUDIO_SAIx_MCK_SCK_SD_FS_AF;
01067   HAL_GPIO_Init(AUDIO_SAIx_MCK_SCK_SD_FS_GPIO_PORT, &GPIO_InitStruct);
01068 
01069   /* Enable the DMA clock */
01070   AUDIO_SAIx_DMAx_CLK_ENABLE();
01071     
01072   if(hsai->Instance == AUDIO_SAIx)
01073   {
01074     /* Configure the hDmaSai handle parameters */   
01075     hDmaSai.Init.Request             = DMA_REQUEST_1;
01076     hDmaSai.Init.Direction           = DMA_MEMORY_TO_PERIPH;
01077     hDmaSai.Init.PeriphInc           = DMA_PINC_DISABLE;
01078     hDmaSai.Init.MemInc              = DMA_MINC_ENABLE;
01079     hDmaSai.Init.PeriphDataAlignment = AUDIO_SAIx_DMAx_PERIPH_DATA_SIZE;
01080     hDmaSai.Init.MemDataAlignment    = AUDIO_SAIx_DMAx_MEM_DATA_SIZE;
01081     hDmaSai.Init.Mode                = DMA_NORMAL;
01082     hDmaSai.Init.Priority            = DMA_PRIORITY_HIGH;
01083     
01084     hDmaSai.Instance = AUDIO_SAIx_DMAx_CHANNEL;
01085     
01086     /* Associate the DMA handle */
01087     __HAL_LINKDMA(hsai, hdmatx, hDmaSai);
01088     
01089     /* Deinitialize the Stream for new transfer */
01090     HAL_DMA_DeInit(&hDmaSai);
01091     
01092     /* Configure the DMA Stream */
01093     HAL_DMA_Init(&hDmaSai);      
01094   }
01095   
01096   /* SAI DMA IRQ Channel configuration */
01097   HAL_NVIC_SetPriority(AUDIO_SAIx_DMAx_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0);
01098   HAL_NVIC_EnableIRQ(AUDIO_SAIx_DMAx_IRQ); 
01099 }
01100 
01101 /**
01102   * @brief  SAI MSP De-init
01103   * @param  hsai : pointer to a SAI_HandleTypeDef structure
01104   * @retval None
01105   */
01106 void HAL_SAI_MspDeInit(SAI_HandleTypeDef *hsai)
01107 {
01108   /* Disable SAI DMA Channel IRQ  */
01109   HAL_NVIC_DisableIRQ(AUDIO_SAIx_DMAx_IRQ); 
01110 
01111   /* Reset the DMA Stream configuration*/
01112   HAL_DMA_DeInit(&hDmaSai);
01113   
01114   /* Disable the DMA clock */
01115   AUDIO_SAIx_DMAx_CLK_DISABLE();
01116     
01117   /* De-initialize FS, SCK, MCK and SD pins*/
01118   HAL_GPIO_DeInit(AUDIO_SAIx_MCK_SCK_SD_FS_GPIO_PORT, 
01119                   AUDIO_SAIx_FS_PIN | AUDIO_SAIx_SCK_PIN | AUDIO_SAIx_SD_PIN | AUDIO_SAIx_MCK_PIN);
01120   
01121   /* Disable GPIO clock */
01122   AUDIO_SAIx_MCK_SCK_SD_FS_DISABLE();
01123   
01124   /* Disable SAI clock */
01125   AUDIO_SAIx_CLK_DISABLE();
01126 }
01127 
01128 /**
01129   * @brief  Resets the audio codec. It restores the default configuration of the 
01130   *         codec (this function shall be called before initializing the codec).
01131   * @retval None
01132   */
01133 //static void AUDIO_CODEC_Reset(void)
01134 //{
01135 //  /* Initialize the audio driver structure */
01136 //  hAudioOut.AudioDrv = &cs43l22_drv; 
01137 //  
01138 //  hAudioOut.AudioDrv->Reset(AUDIO_I2C_ADDRESS);
01139 //}
01140 
01141 /**
01142   * @}
01143   */
01144 
01145 /** @addtogroup STM32L476G_NUCLEO_AUDIO_Private_Functions
01146   * @{
01147   */ 
01148 
01149 /**
01150   * @brief  Initializes the Digital Filter for Sigma-Delta Modulators interface (DFSDM).
01151   * @param  AudioFreq: Audio frequency to be used to set correctly the DFSDM peripheral.
01152   * @retval BSP AUDIO status
01153   */
01154 static uint8_t AUDIO_DFSDMx_Init(uint32_t AudioFreq)
01155 {
01156   /*####CHANNEL 2####*/
01157   hAudioIn.hDfsdmLeftChannel.Init.OutputClock.Activation   = ENABLE;
01158   hAudioIn.hDfsdmLeftChannel.Init.OutputClock.Selection    = DFSDM_CHANNEL_OUTPUT_CLOCK_AUDIO;
01159   /* Set the DFSDM clock OUT audio frequency configuration */
01160   hAudioIn.hDfsdmLeftChannel.Init.OutputClock.Divider      = DFSDMClockDivider(AudioFreq);
01161   hAudioIn.hDfsdmLeftChannel.Init.Input.Multiplexer        = DFSDM_CHANNEL_EXTERNAL_INPUTS;
01162   hAudioIn.hDfsdmLeftChannel.Init.Input.DataPacking        = DFSDM_CHANNEL_STANDARD_MODE;
01163   hAudioIn.hDfsdmLeftChannel.Init.Input.Pins               = DFSDM_CHANNEL_SAME_CHANNEL_PINS;
01164   /* Request to sample stable data for LEFT micro on Rising edge */
01165   hAudioIn.hDfsdmLeftChannel.Init.SerialInterface.Type     = DFSDM_CHANNEL_SPI_RISING;
01166   hAudioIn.hDfsdmLeftChannel.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
01167   hAudioIn.hDfsdmLeftChannel.Init.Awd.FilterOrder          = DFSDM_CHANNEL_SINC1_ORDER;
01168   hAudioIn.hDfsdmLeftChannel.Init.Awd.Oversampling         = 10;
01169   hAudioIn.hDfsdmLeftChannel.Init.Offset                   = 0;
01170   hAudioIn.hDfsdmLeftChannel.Init.RightBitShift            = DFSDMRightBitShift(AudioFreq);
01171 
01172   hAudioIn.hDfsdmLeftChannel.Instance                      = DFSDM_Channel2;
01173 
01174     /* Init the DFSDM Channel */
01175   if (HAL_DFSDM_ChannelInit(&hAudioIn.hDfsdmLeftChannel) != HAL_OK)
01176   {
01177     return AUDIO_ERROR;
01178   }
01179 
01180   /*####FILTER 0####*/
01181   BSP_AUDIO_hDfsdmLeftFilter.Init.RegularParam.Trigger         = DFSDM_FILTER_SW_TRIGGER;
01182   BSP_AUDIO_hDfsdmLeftFilter.Init.RegularParam.FastMode        = ENABLE;
01183   BSP_AUDIO_hDfsdmLeftFilter.Init.RegularParam.DmaMode         = ENABLE;
01184   BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.Trigger        = DFSDM_FILTER_SW_TRIGGER;
01185   BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.ScanMode       = DISABLE;
01186   BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.DmaMode        = DISABLE;
01187   BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.ExtTrigger     = DFSDM_FILTER_EXT_TRIG_TIM8_TRGO;
01188   BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.ExtTriggerEdge = DFSDM_FILTER_EXT_TRIG_BOTH_EDGES;
01189   BSP_AUDIO_hDfsdmLeftFilter.Init.FilterParam.SincOrder        = DFSDMFilterOrder(AudioFreq);
01190   /* Set the DFSDM Filters Oversampling to have correct sample rate */
01191   BSP_AUDIO_hDfsdmLeftFilter.Init.FilterParam.Oversampling     = DFSDMOverSampling(AudioFreq);
01192   BSP_AUDIO_hDfsdmLeftFilter.Init.FilterParam.IntOversampling  = 1;
01193   
01194   BSP_AUDIO_hDfsdmLeftFilter.Instance                          = AUDIO_DFSDMx_LEFT_FILTER;
01195 
01196     /* Init the DFSDM Filter */
01197   if (HAL_DFSDM_FilterInit(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK)
01198   {
01199     return AUDIO_ERROR;
01200   }
01201   
01202   /* Configure regular channel */
01203   if (HAL_DFSDM_FilterConfigRegChannel(&BSP_AUDIO_hDfsdmLeftFilter, 
01204                                       DFSDM_CHANNEL_2, 
01205                                       DFSDM_CONTINUOUS_CONV_ON) != HAL_OK)
01206   {
01207     return AUDIO_ERROR;
01208   }
01209 
01210   return AUDIO_OK;
01211 }
01212 
01213 /**
01214   * @brief  De-initializes the Digital Filter for Sigma-Delta Modulators interface (DFSDM).
01215   * @retval BSP AUDIO status
01216   */
01217 static uint8_t AUDIO_DFSDMx_DeInit(void)
01218 {
01219   /* De-initializes the DFSDM filters to allow access to DFSDM internal registers */
01220   if (HAL_DFSDM_FilterDeInit(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK)
01221   {
01222     return AUDIO_ERROR;
01223   }
01224 
01225   /* De-initializes the DFSDM channels to allow access to DFSDM internal registers */
01226   if (HAL_DFSDM_ChannelDeInit(&hAudioIn.hDfsdmLeftChannel) != HAL_OK)
01227   {
01228     return AUDIO_ERROR;
01229   }
01230 
01231   /* Disable DFSDM clock */
01232   AUDIO_DFSDMx_CLK_DISABLE();
01233 
01234   /* Disable SAIx PLL */
01235   if (AUDIO_SAIx_PLL_DISABLE() != AUDIO_OK)
01236   {
01237     return AUDIO_ERROR;
01238   }  
01239 
01240   /* DFSDM reset */
01241   __HAL_RCC_DFSDM_FORCE_RESET();
01242   __HAL_RCC_DFSDM_RELEASE_RESET();
01243 
01244   return AUDIO_OK;
01245 }
01246 
01247 /**
01248   * @brief  Initializes the DFSDM channel MSP.
01249   * @param  hdfsdm_channel : DFSDM channel handle.
01250   * @retval None
01251   */
01252 void HAL_DFSDM_ChannelMspInit(DFSDM_Channel_HandleTypeDef *hdfsdm_channel)
01253 {
01254   GPIO_InitTypeDef  GPIO_InitStruct;  
01255 
01256   /* Enable DFSDM clock */
01257   AUDIO_DFSDMx_CLK_ENABLE();
01258   
01259   /* Enable GPIO clock */
01260   AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_CLK_ENABLE();
01261   
01262   /* DFSDM pins configuration: DFSDM_CKOUT, DMIC_DATIN pins ------------------*/
01263   GPIO_InitStruct.Pin = AUDIO_DFSDMx_CKOUT_PIN | AUDIO_DFSDMx_DMIC_DATIN_PIN;
01264   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
01265   GPIO_InitStruct.Pull = GPIO_NOPULL;
01266   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
01267   GPIO_InitStruct.Alternate = AUDIO_DFSDMx_CKOUT_DMIC_DATIN_AF;
01268   HAL_GPIO_Init(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, &GPIO_InitStruct);
01269 }
01270 
01271 /**
01272   * @brief  De-initializes the DFSDM channel MSP.
01273   * @param  hdfsdm_channel : DFSDM channel handle.
01274   * @retval None
01275   */
01276 void HAL_DFSDM_ChannelMspDeInit(DFSDM_Channel_HandleTypeDef *hdfsdm_channel)
01277 {
01278   GPIO_InitTypeDef  GPIO_InitStruct;
01279   
01280   /* Enable GPIO clock */
01281   AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_CLK_ENABLE();
01282   
01283   /* DFSDM pins configuration: DFSDM_CKOUT */
01284   GPIO_InitStruct.Pin = AUDIO_DFSDMx_CKOUT_PIN;
01285   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
01286   GPIO_InitStruct.Pull = GPIO_NOPULL;
01287   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
01288   HAL_GPIO_Init(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, &GPIO_InitStruct);
01289   HAL_GPIO_WritePin(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, AUDIO_DFSDMx_CKOUT_PIN, GPIO_PIN_RESET);
01290 
01291 
01292   /* De-initialize DMIC_DATIN pin */
01293   HAL_GPIO_DeInit(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, AUDIO_DFSDMx_DMIC_DATIN_PIN);
01294 }
01295 
01296 /**
01297   * @brief  Initializes the DFSDM filter MSP.
01298   * @param  hdfsdm_filter : DFSDM filter handle.
01299   * @retval None
01300   */
01301 void HAL_DFSDM_FilterMspInit(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
01302 {
01303   /* Enable DFSDM clock */
01304   AUDIO_DFSDMx_CLK_ENABLE();
01305   
01306   /* Enable the DMA clock */
01307   AUDIO_DFSDMx_DMAx_CLK_ENABLE();
01308     
01309   /* Configure the hAudioIn.hDmaDfsdmLeft handle parameters */   
01310   hAudioIn.hDmaDfsdmLeft.Init.Request             = DMA_REQUEST_0;
01311   hAudioIn.hDmaDfsdmLeft.Init.Direction           = DMA_PERIPH_TO_MEMORY;
01312   hAudioIn.hDmaDfsdmLeft.Init.PeriphInc           = DMA_PINC_DISABLE;
01313   hAudioIn.hDmaDfsdmLeft.Init.MemInc              = DMA_MINC_ENABLE;
01314   hAudioIn.hDmaDfsdmLeft.Init.PeriphDataAlignment = AUDIO_DFSDMx_DMAx_PERIPH_DATA_SIZE;
01315   hAudioIn.hDmaDfsdmLeft.Init.MemDataAlignment    = AUDIO_DFSDMx_DMAx_MEM_DATA_SIZE;
01316   hAudioIn.hDmaDfsdmLeft.Init.Mode                = DMA_CIRCULAR;
01317   hAudioIn.hDmaDfsdmLeft.Init.Priority            = DMA_PRIORITY_HIGH;
01318 
01319   hAudioIn.hDmaDfsdmLeft.Instance               = AUDIO_DFSDMx_DMAx_LEFT_CHANNEL;
01320   
01321   /* Associate the DMA handle */
01322   __HAL_LINKDMA(hdfsdm_filter, hdmaReg, hAudioIn.hDmaDfsdmLeft);
01323   
01324   /* Reset DMA handle state */
01325   __HAL_DMA_RESET_HANDLE_STATE(&hAudioIn.hDmaDfsdmLeft);
01326 
01327   /* Configure the DMA Channel */
01328   HAL_DMA_Init(&hAudioIn.hDmaDfsdmLeft);      
01329 
01330   /* DMA IRQ Channel configuration */
01331     HAL_NVIC_SetPriority(AUDIO_DFSDMx_DMAx_LEFT_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0);
01332     HAL_NVIC_EnableIRQ(AUDIO_DFSDMx_DMAx_LEFT_IRQ);
01333   }
01334 
01335  /**
01336   * @brief  De-initializes the DFSDM filter MSP.
01337   * @param  hdfsdm_filter : DFSDM filter handle.
01338   * @retval None
01339   */
01340 void HAL_DFSDM_FilterMspDeInit(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
01341 {
01342   /* Disable DMA  Channel IRQ */
01343   HAL_NVIC_DisableIRQ(AUDIO_DFSDMx_DMAx_LEFT_IRQ);
01344 
01345   /* De-initialize the DMA Channel */
01346   HAL_DMA_DeInit(&hAudioIn.hDmaDfsdmLeft);      
01347 
01348   /* Disable the DMA clock */
01349   AUDIO_DFSDMx_DMAx_CLK_DISABLE();
01350 }
01351 
01352 /**
01353   * @brief  Configures the SAI PLL clock according to the required audio frequency.
01354   * @param  Frequency: Audio frequency.  
01355   * @retval BSP AUDIO status
01356   * @note   The SAI PLL input clock must be configured in the user application.
01357   *         The SAI PLL configuration done within this function assumes that
01358   *         the SAI PLL input clock runs at 8 MHz.
01359   */
01360 static uint8_t AUDIO_SAIPLLConfig(uint32_t Frequency)
01361 {
01362   RCC_PeriphCLKInitTypeDef RCC_ExCLKInitStruct;
01363 
01364   /* Retreive actual RCC configuration */
01365   HAL_RCCEx_GetPeriphCLKConfig(&RCC_ExCLKInitStruct);
01366   
01367     if (   (Frequency == AUDIO_FREQUENCY_11K) 
01368         || (Frequency == AUDIO_FREQUENCY_22K)
01369         || (Frequency == AUDIO_FREQUENCY_44K) )
01370   {
01371     /* Configure PLLSAI prescalers */
01372     /* SAI clock config 
01373     PLLSAI1_VCO= 8 Mhz * PLLSAI1N = 8 * 24 = VCO_192M 
01374     SAI_CK_x = PLLSAI1_VCO/PLLSAI1P = 192/17 = 11.294 Mhz */  
01375     RCC_ExCLKInitStruct.PeriphClockSelection    = RCC_PERIPHCLK_SAI1;
01376     RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1N        = 24; 
01377     RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1P        = 17; 
01378     RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK;
01379     RCC_ExCLKInitStruct.Sai1ClockSelection      = RCC_SAI1CLKSOURCE_PLLSAI1;
01380   }
01381   else /* AUDIO_FREQUENCY_8K, AUDIO_FREQUENCY_16K, AUDIO_FREQUENCY_48K, AUDIO_FREQUENCY_96K */
01382   {
01383     /* SAI clock config 
01384     PLLSAI1_VCO= 8 Mhz * PLLSAI1N = 8 * 43 = VCO_344M 
01385     SAI_CK_x = PLLSAI1_VCO/PLLSAI1P = 344/7 = 49.142 Mhz */  
01386     RCC_ExCLKInitStruct.PeriphClockSelection    = RCC_PERIPHCLK_SAI1;
01387     RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1N        = 43;
01388     RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1P        = 7;
01389     RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK;
01390     RCC_ExCLKInitStruct.Sai1ClockSelection      = RCC_SAI1CLKSOURCE_PLLSAI1;
01391   }
01392   
01393   if (HAL_RCCEx_PeriphCLKConfig(&RCC_ExCLKInitStruct) != HAL_OK)
01394   {
01395     return AUDIO_ERROR;
01396   }    
01397 
01398   return AUDIO_OK;
01399 }
01400 
01401 /**
01402   * @}
01403   */
01404 
01405 /**
01406   * @}
01407   */
01408 
01409 /**
01410   * @}
01411   */
01412 
01413 /**
01414   * @}
01415   */
01416 
01417 /**
01418   * @}
01419   */
01420 
01421 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
01422