Senior Design: Sound Monitor / OneHopeOnePrayer

Dependencies:   STM32L4xx_HAL_Driver CMSIS_DSP_401

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32l476g_discovery_audio.c Source File

stm32l476g_discovery_audio.c

Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l476g_discovery_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-Discovery 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-Discovery (MB1184) Discovery 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 stm32l476g_discovery_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 stm32l476g_discovery_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 "stm32l476g_discovery_audio.h"
00129 
00130 /** @addtogroup BSP
00131   * @{
00132   */
00133 
00134 /** @addtogroup STM32L476G_DISCOVERY
00135   * @{
00136   */
00137 
00138 /** @defgroup STM32L476G_DISCOVERY_AUDIO STM32L476G-DISCOVERY AUDIO
00139   * @brief This file includes the low layer driver for cs43l22 Audio Codec
00140   *        available on STM32L476G-Discovery board(MB1184).
00141   * @{
00142   */ 
00143 
00144 /* Private typedef -----------------------------------------------------------*/
00145 /** @defgroup STM32L476G_DISCOVERY_AUDIO_Private_Types Private Types
00146   * @{
00147   */
00148 typedef struct
00149 {
00150   
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_DISCOVERY_AUDIO_Private_Constants Private Constants
00177   * @{
00178   */
00179 /**
00180   * @}
00181   */
00182 
00183 /* Private macros ------------------------------------------------------------*/
00184 /** @defgroup STM32L476G_DISCOVERY_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_DISCOVERY_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_DISCOVERY_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_DISCOVERY_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_DISCOVERY_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 
00302 /**
00303   * @brief  Tx Transfer completed callbacks.
00304   * @param  hsai: SAI handle
00305   * @retval None
00306   */
00307 void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
00308 {
00309   /* Invoke the registered 'TransferComplete' function (if any) */
00310   if (hAudioOut.CbTransferComplete != (Audio_CallbackTypeDef)NULL)
00311   {
00312     hAudioOut.CbTransferComplete();
00313   }
00314 }
00315 
00316 /**
00317   * @brief  Tx Half Transfer completed callbacks.
00318   * @param  hsai: SAI handle
00319   * @retval None
00320   */
00321 void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
00322 {
00323   /* Invoke the registered 'HalfTransfer' callback function (if any) */
00324   if (hAudioOut.CbHalfTransfer != (Audio_CallbackTypeDef)NULL)
00325   {
00326     hAudioOut.CbHalfTransfer();
00327   }
00328 }
00329 
00330 /**
00331   * @brief  SAI error callbacks.
00332   * @param  hsai: SAI handle
00333   * @retval None
00334   */
00335 void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai)
00336 {
00337   /* Invoke the registered 'ErrorCallback' callback function (if any) */
00338   if (hAudioOut.CbError != (Audio_CallbackTypeDef)NULL)
00339   {
00340     hAudioOut.CbError();
00341   }
00342 }
00343 
00344 /**
00345   * @}
00346   */
00347 
00348 /** @addtogroup STM32L476G_EVAL_AUDIO_Exported_Functions
00349   * @{
00350   */
00351   
00352 /**
00353   * @brief  Initializes micropone related peripherals.
00354   * @note   This function assumes that the SAI input clock (through PLL_M)
00355   *         is already configured and ready to be used.  
00356   * @param  AudioFreq: Audio frequency to be configured for the SAI peripheral. 
00357   * @param  BitRes: Audio frequency to be configured for the SAI peripheral.
00358   * @param  ChnlNbr: Audio frequency to be configured for the SAI peripheral.
00359   * @retval BSP AUDIO status
00360   */
00361 uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
00362 {
00363   /* Update the audio input context */
00364   hAudioIn.Frequency          = AudioFreq;
00365   hAudioIn.BitResolution      = BitRes;
00366   hAudioIn.ChannelNbr         = ChnlNbr;
00367   hAudioIn.CbError            = (Audio_CallbackTypeDef)NULL; 
00368   hAudioIn.CbHalfTransfer     = (Audio_CallbackTypeDef)NULL; 
00369   hAudioIn.CbTransferComplete = (Audio_CallbackTypeDef)NULL;
00370 
00371   /* Configure the SAI PLL according to the requested audio frequency */
00372   if (AUDIO_SAIPLLConfig(AudioFreq) != AUDIO_OK)
00373   {
00374     return AUDIO_ERROR;
00375   }
00376  
00377   /* Initializes the Digital Filter for Sigma-Delta Modulators interface */
00378   if(AUDIO_DFSDMx_Init(AudioFreq) != AUDIO_OK)
00379   {
00380     return AUDIO_ERROR;
00381   }
00382   
00383   return AUDIO_OK;
00384   }
00385 
00386 /**
00387   * @brief  De-Initializes microphone related peripherals.
00388   * @retval BSP AUDIO status
00389 
00390   */
00391 uint8_t BSP_AUDIO_IN_DeInit(void)
00392 {
00393   /* De-initializes the Digital Filter for Sigma-Delta Modulators interface */
00394   if (AUDIO_DFSDMx_DeInit() != AUDIO_OK)
00395   {
00396     return AUDIO_ERROR;
00397   }
00398   
00399   /* Reset the audio input context */
00400   memset(&hAudioIn, 0, sizeof(hAudioIn));
00401 
00402   return AUDIO_OK;
00403 }
00404 
00405 /**
00406   * @brief  Starts audio recording.
00407   * @param  pbuf: Main buffer pointer for the recorded data storing  
00408   * @param  size: Current size of the recorded buffer
00409   * @note   The Right channel is start at first with synchro on start of Left channel
00410   * @retval BSP AUDIO status
00411   */
00412 uint8_t BSP_AUDIO_IN_Record(uint16_t* pbuf, uint32_t size)
00413 {
00414   hAudioIn.pRecBuf = pbuf;
00415   hAudioIn.RecSize = size;
00416 
00417   /* Allocate hAudioIn.LeftRecBuff buffer */
00418 #if defined(BSP_AUDIO_USE_RTOS)
00419   hAudioIn.LeftRecBuff  = (int32_t *)k_malloc(size * sizeof(int32_t));
00420 #else
00421   hAudioIn.LeftRecBuff  = (int32_t *)malloc(size * sizeof(int32_t));
00422 #endif
00423   if(hAudioIn.LeftRecBuff == NULL)
00424   {
00425     return AUDIO_ERROR;
00426   }
00427 
00428   /* Call the Media layer start function for left channel */
00429   if(HAL_DFSDM_FilterRegularStart_DMA(&BSP_AUDIO_hDfsdmLeftFilter, 
00430                                       (int32_t*)hAudioIn.LeftRecBuff, 
00431                                       (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR)) != HAL_OK)
00432   {
00433     return AUDIO_ERROR;
00434   }
00435 
00436   return AUDIO_OK;
00437 }
00438 
00439 /**
00440   * @brief  Updates the audio frequency.
00441   * @param  AudioFreq: Audio frequency used to record the audio stream.
00442   * @note   This API should be called after the BSP_AUDIO_IN_Init() to adjust the
00443   *         audio frequency.
00444   * @retval BSP AUDIO status
00445   */
00446 uint8_t BSP_AUDIO_IN_SetFrequency(uint32_t AudioFreq)
00447 { 
00448   /* Configure the SAI PLL according to the requested audio frequency */
00449   if (AUDIO_SAIPLLConfig(AudioFreq) != AUDIO_OK)
00450   {
00451     return AUDIO_ERROR;
00452   }
00453 
00454   /* De-initializes the Digital Filter for Sigma-Delta Modulators interface */
00455   if(AUDIO_DFSDMx_DeInit() != AUDIO_OK)
00456   {
00457     return AUDIO_ERROR;
00458   }
00459   
00460   /* Initializes the Digital Filter for Sigma-Delta Modulators interface */
00461   if(AUDIO_DFSDMx_Init(AudioFreq) != AUDIO_OK)
00462   {
00463     return AUDIO_ERROR;
00464   }
00465   
00466   return AUDIO_OK;
00467 }
00468 
00469 /**
00470   * @brief  Regular conversion complete callback. 
00471   * @note   In interrupt mode, user has to read conversion value in this function
00472             using HAL_DFSDM_FilterGetRegularValue.
00473   * @param  hdfsdm_filter : DFSDM filter handle.
00474   * @retval None
00475   */
00476 void HAL_DFSDM_FilterRegConvCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
00477 {
00478   uint32_t index;
00479   uint32_t recbufsize = (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR);
00480   
00481   for(index = (recbufsize/2); index < recbufsize; index++)
00482   {
00483     hAudioIn.pRecBuf[index] = (uint16_t)(SaturaLH((hAudioIn.LeftRecBuff[index] >> 8), -32760, 32760));
00484   }
00485   
00486   /* Invoke the registered 'TransferComplete' function (if any) */
00487   if (hAudioIn.CbTransferComplete != (Audio_CallbackTypeDef)NULL)
00488   {
00489     hAudioIn.CbTransferComplete();
00490   }
00491 }
00492 
00493 /**
00494   * @brief  Half regular conversion complete callback. 
00495   * @param  hdfsdm_filter : DFSDM filter handle.
00496   * @retval None
00497   */
00498 void HAL_DFSDM_FilterRegConvHalfCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
00499 {
00500   uint32_t index;
00501   uint32_t recbufsize = (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR);
00502   
00503   
00504   for(index = 0; index < (recbufsize/2); index++)
00505   {
00506     hAudioIn.pRecBuf[index] = (uint16_t)(SaturaLH((hAudioIn.LeftRecBuff[index] >> 8), -32760, 32760));
00507   }
00508   
00509   /* Invoke the registered 'HalfTransfer' callback function (if any) */
00510   if (hAudioIn.CbHalfTransfer != (Audio_CallbackTypeDef)NULL)
00511   {
00512     hAudioIn.CbHalfTransfer();
00513   }
00514 }
00515 
00516 /**
00517   * @brief  Error callback. 
00518   * @param  hdfsdm_filter : DFSDM filter handle.
00519   * @retval None
00520   */
00521 void HAL_DFSDM_FilterErrorCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
00522 {
00523   /* Invoke the registered 'ErrorCallback' callback function (if any) */
00524   if (hAudioIn.CbError != (Audio_CallbackTypeDef)NULL)
00525   {
00526     hAudioIn.CbError();
00527   }
00528 }
00529 
00530 /**
00531   * @brief  Stops audio recording.
00532   * @retval BSP AUDIO status
00533   */
00534 uint8_t BSP_AUDIO_IN_Stop(void)
00535 {
00536   /* Call the Media layer stop function for left channel */
00537   if(HAL_DFSDM_FilterRegularStop_DMA(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK )
00538   {
00539     return AUDIO_ERROR;
00540   }
00541 
00542   /* Free hAudioIn.LeftRecBuff buffer */
00543 #if defined(BSP_AUDIO_USE_RTOS)
00544   k_free((void *)hAudioIn.LeftRecBuff);
00545 #else
00546   free((void *)hAudioIn.LeftRecBuff);
00547 #endif
00548   
00549   return AUDIO_OK;
00550 }
00551 
00552 /**
00553   * @brief  Pauses the audio file stream.
00554   * @retval BSP AUDIO status
00555   */
00556 uint8_t BSP_AUDIO_IN_Pause(void)
00557 {    
00558   /* Call the Media layer stop function */
00559   if(HAL_DFSDM_FilterRegularStop_DMA(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK)
00560   {
00561     return AUDIO_ERROR;
00562   }
00563   
00564   return AUDIO_OK;
00565 }
00566 
00567 /**
00568   * @brief  Resumes the audio file stream.
00569   * @retval BSP AUDIO status
00570   */
00571 uint8_t BSP_AUDIO_IN_Resume(void)
00572 {    
00573   /* Call the Media layer start function for left channel */
00574   if(HAL_DFSDM_FilterRegularStart_DMA(&BSP_AUDIO_hDfsdmLeftFilter,
00575                                       (int32_t*)hAudioIn.LeftRecBuff,
00576                                       (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR)) != HAL_OK)
00577   {
00578     return AUDIO_ERROR;
00579   }
00580   
00581   return AUDIO_OK;
00582 }
00583 
00584 /**
00585   * @brief  register user callback functions 
00586   * @param  ErrorCallback: pointer to the error callback function
00587   * @param  HalfTransferCallback: pointer to the half transfer callback function
00588   * @param  TransferCompleteCallback: pointer to the transfer complete callback function
00589   * @retval None
00590   */
00591 void BSP_AUDIO_IN_RegisterCallbacks(Audio_CallbackTypeDef ErrorCallback,
00592                                     Audio_CallbackTypeDef HalfTransferCallback, 
00593                                     Audio_CallbackTypeDef TransferCompleteCallback)
00594 {
00595   hAudioIn.CbError            = ErrorCallback; 
00596   hAudioIn.CbHalfTransfer     = HalfTransferCallback; 
00597   hAudioIn.CbTransferComplete = TransferCompleteCallback;
00598 }
00599 /**
00600   * @}
00601   */
00602 
00603 /* private functions --------------------------------------------------------*/
00604 /** @addtogroup STM32L476G_DISCOVERY_AUDIO_Private_Functions
00605   * @{
00606   */
00607 /**
00608   * @brief  Initializes the Audio Codec audio interface (SAI).
00609   * @param  AudioFreq: Audio frequency to be configured for the SAI peripheral.
00610   * @note   The default SlotActive configuration is set to CODEC_AUDIOFRAME_SLOT_0123 
00611   *         and user can update this configuration using 
00612   * @retval BSP AUDIO status
00613   */
00614 static uint8_t AUDIO_SAIx_Init(uint32_t AudioFreq)
00615 {
00616   /* Disable SAI peripheral to allow access to SAI internal registers */
00617   __HAL_SAI_DISABLE(&BSP_AUDIO_hSai);
00618   
00619   /* Initialize the BSP_AUDIO_hSai Instance parameter */
00620   BSP_AUDIO_hSai.Instance = AUDIO_SAIx;
00621   
00622   /* Configure SAI_Block_x 
00623   LSBFirst: Disabled 
00624   DataSize: 16 */
00625   BSP_AUDIO_hSai.Init.AudioMode      = SAI_MODEMASTER_TX;
00626   BSP_AUDIO_hSai.Init.Synchro        = SAI_ASYNCHRONOUS;
00627   BSP_AUDIO_hSai.Init.SynchroExt     = SAI_SYNCEXT_DISABLE;
00628   BSP_AUDIO_hSai.Init.OutputDrive    = SAI_OUTPUTDRIVE_ENABLE;
00629   BSP_AUDIO_hSai.Init.NoDivider      = SAI_MASTERDIVIDER_ENABLE;
00630   BSP_AUDIO_hSai.Init.FIFOThreshold  = SAI_FIFOTHRESHOLD_1QF;
00631   BSP_AUDIO_hSai.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_MCKDIV;
00632   BSP_AUDIO_hSai.Init.Mckdiv         = SAIClockDivider(AudioFreq);
00633   BSP_AUDIO_hSai.Init.MonoStereoMode = SAI_STEREOMODE;
00634   BSP_AUDIO_hSai.Init.CompandingMode = SAI_NOCOMPANDING;
00635   BSP_AUDIO_hSai.Init.TriState       = SAI_OUTPUT_NOTRELEASED;
00636   BSP_AUDIO_hSai.Init.Protocol       = SAI_FREE_PROTOCOL;
00637   BSP_AUDIO_hSai.Init.DataSize       = SAI_DATASIZE_16;
00638   BSP_AUDIO_hSai.Init.FirstBit       = SAI_FIRSTBIT_MSB;
00639   BSP_AUDIO_hSai.Init.ClockStrobing  = SAI_CLOCKSTROBING_RISINGEDGE;
00640   
00641   /* Configure SAI_Block_x Frame 
00642   Frame Length: 32
00643   Frame active Length: 16
00644   FS Definition: Start frame + Channel Side identification
00645   FS Polarity: FS active Low
00646   FS Offset: FS asserted one bit before the first bit of slot 0 */ 
00647   BSP_AUDIO_hSai.FrameInit.FrameLength = 32;
00648   BSP_AUDIO_hSai.FrameInit.ActiveFrameLength = 16;
00649   BSP_AUDIO_hSai.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
00650   BSP_AUDIO_hSai.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
00651   BSP_AUDIO_hSai.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
00652   
00653   /* Configure SAI Block_x Slot 
00654   Slot First Bit Offset: 0
00655   Slot Size  : 16
00656   Slot Number: 2
00657   Slot Active: Slots 0 and 1 actives */
00658   BSP_AUDIO_hSai.SlotInit.FirstBitOffset = 0;
00659   BSP_AUDIO_hSai.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
00660   BSP_AUDIO_hSai.SlotInit.SlotNumber = 2; 
00661   BSP_AUDIO_hSai.SlotInit.SlotActive = SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1;
00662 
00663   /* Initializes the SAI peripheral*/
00664   if (HAL_SAI_Init(&BSP_AUDIO_hSai) != HAL_OK)
00665   {
00666     return AUDIO_ERROR;
00667   }
00668   
00669   /* Enable SAI peripheral to generate MCLK */
00670   __HAL_SAI_ENABLE(&BSP_AUDIO_hSai);
00671   
00672   return AUDIO_OK;
00673   
00674 }
00675 
00676 /**
00677   * @brief  De-initializes the Audio Codec audio interface (SAI).
00678   * @retval BSP AUDIO status
00679   */
00680 static uint8_t AUDIO_SAIx_DeInit(void)
00681 {
00682   /* Disable the SAI audio block */
00683   __HAL_SAI_DISABLE(&BSP_AUDIO_hSai);
00684 
00685   /* De-initializes the SAI peripheral */
00686   if (HAL_SAI_DeInit(&BSP_AUDIO_hSai) != HAL_OK)
00687   {
00688     return AUDIO_ERROR;
00689   }
00690   
00691   /* Disable SAIx PLL */
00692   if (AUDIO_SAIx_PLL_DISABLE() != AUDIO_OK)
00693   {
00694     return AUDIO_ERROR;
00695   }  
00696   
00697   return AUDIO_OK;
00698 }
00699 
00700 /**
00701   * @brief  SAI MSP Init
00702   * @param  hsai : pointer to a SAI_HandleTypeDef structure
00703   * @retval None
00704   */
00705 void HAL_SAI_MspInit(SAI_HandleTypeDef *hsai)
00706 { 
00707   GPIO_InitTypeDef  GPIO_InitStruct;  
00708 
00709   /* Enable SAI clock */
00710   AUDIO_SAIx_CLK_ENABLE();
00711   
00712   /* Enable GPIO clock */
00713   AUDIO_SAIx_MCK_SCK_SD_FS_ENABLE();
00714   
00715   /* CODEC_SAI pins configuration: FS, SCK, MCK and SD pins ------------------*/
00716   GPIO_InitStruct.Pin = AUDIO_SAIx_FS_PIN | AUDIO_SAIx_SCK_PIN | AUDIO_SAIx_SD_PIN | AUDIO_SAIx_MCK_PIN;
00717   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
00718   GPIO_InitStruct.Pull = GPIO_NOPULL;
00719   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
00720   GPIO_InitStruct.Alternate = AUDIO_SAIx_MCK_SCK_SD_FS_AF;
00721   HAL_GPIO_Init(AUDIO_SAIx_MCK_SCK_SD_FS_GPIO_PORT, &GPIO_InitStruct);
00722 
00723   /* Enable the DMA clock */
00724   AUDIO_SAIx_DMAx_CLK_ENABLE();
00725     
00726   if(hsai->Instance == AUDIO_SAIx)
00727   {
00728     /* Configure the hDmaSai handle parameters */   
00729     hDmaSai.Init.Request             = DMA_REQUEST_1;
00730     hDmaSai.Init.Direction           = DMA_MEMORY_TO_PERIPH;
00731     hDmaSai.Init.PeriphInc           = DMA_PINC_DISABLE;
00732     hDmaSai.Init.MemInc              = DMA_MINC_ENABLE;
00733     hDmaSai.Init.PeriphDataAlignment = AUDIO_SAIx_DMAx_PERIPH_DATA_SIZE;
00734     hDmaSai.Init.MemDataAlignment    = AUDIO_SAIx_DMAx_MEM_DATA_SIZE;
00735     hDmaSai.Init.Mode                = DMA_NORMAL;
00736     hDmaSai.Init.Priority            = DMA_PRIORITY_HIGH;
00737     
00738     hDmaSai.Instance = AUDIO_SAIx_DMAx_CHANNEL;
00739     
00740     /* Associate the DMA handle */
00741     __HAL_LINKDMA(hsai, hdmatx, hDmaSai);
00742     
00743     /* Deinitialize the Stream for new transfer */
00744     HAL_DMA_DeInit(&hDmaSai);
00745     
00746     /* Configure the DMA Stream */
00747     HAL_DMA_Init(&hDmaSai);      
00748   }
00749   
00750   /* SAI DMA IRQ Channel configuration */
00751   HAL_NVIC_SetPriority(AUDIO_SAIx_DMAx_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0);
00752   HAL_NVIC_EnableIRQ(AUDIO_SAIx_DMAx_IRQ); 
00753 }
00754 
00755 /**
00756   * @brief  SAI MSP De-init
00757   * @param  hsai : pointer to a SAI_HandleTypeDef structure
00758   * @retval None
00759   */
00760 void HAL_SAI_MspDeInit(SAI_HandleTypeDef *hsai)
00761 {
00762   /* Disable SAI DMA Channel IRQ  */
00763   HAL_NVIC_DisableIRQ(AUDIO_SAIx_DMAx_IRQ); 
00764 
00765   /* Reset the DMA Stream configuration*/
00766   HAL_DMA_DeInit(&hDmaSai);
00767   
00768   /* Disable the DMA clock */
00769   AUDIO_SAIx_DMAx_CLK_DISABLE();
00770     
00771   /* De-initialize FS, SCK, MCK and SD pins*/
00772   HAL_GPIO_DeInit(AUDIO_SAIx_MCK_SCK_SD_FS_GPIO_PORT, 
00773                   AUDIO_SAIx_FS_PIN | AUDIO_SAIx_SCK_PIN | AUDIO_SAIx_SD_PIN | AUDIO_SAIx_MCK_PIN);
00774   
00775   /* Disable GPIO clock */
00776   AUDIO_SAIx_MCK_SCK_SD_FS_DISABLE();
00777   
00778   /* Disable SAI clock */
00779   AUDIO_SAIx_CLK_DISABLE();
00780 }
00781 
00782 /**
00783   * @brief  Resets the audio codec. It restores the default configuration of the 
00784   *         codec (this function shall be called before initializing the codec).
00785   * @retval None
00786   */
00787 
00788 
00789 /**
00790   * @}
00791   */
00792 
00793 /** @addtogroup STM32L476G_DISCOVERY_AUDIO_Private_Functions
00794   * @{
00795   */ 
00796 
00797 /**
00798   * @brief  Initializes the Digital Filter for Sigma-Delta Modulators interface (DFSDM).
00799   * @param  AudioFreq: Audio frequency to be used to set correctly the DFSDM peripheral.
00800   * @retval BSP AUDIO status
00801   */
00802 static uint8_t AUDIO_DFSDMx_Init(uint32_t AudioFreq)
00803 {
00804   /*####CHANNEL 2####*/
00805   hAudioIn.hDfsdmLeftChannel.Init.OutputClock.Activation   = ENABLE;
00806   hAudioIn.hDfsdmLeftChannel.Init.OutputClock.Selection    = DFSDM_CHANNEL_OUTPUT_CLOCK_AUDIO;
00807   /* Set the DFSDM clock OUT audio frequency configuration */
00808   hAudioIn.hDfsdmLeftChannel.Init.OutputClock.Divider      = DFSDMClockDivider(AudioFreq);
00809   hAudioIn.hDfsdmLeftChannel.Init.Input.Multiplexer        = DFSDM_CHANNEL_EXTERNAL_INPUTS;
00810   hAudioIn.hDfsdmLeftChannel.Init.Input.DataPacking        = DFSDM_CHANNEL_STANDARD_MODE;
00811   hAudioIn.hDfsdmLeftChannel.Init.Input.Pins               = DFSDM_CHANNEL_SAME_CHANNEL_PINS;
00812   /* Request to sample stable data for LEFT micro on Rising edge */
00813   hAudioIn.hDfsdmLeftChannel.Init.SerialInterface.Type     = DFSDM_CHANNEL_SPI_RISING;
00814   hAudioIn.hDfsdmLeftChannel.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
00815   hAudioIn.hDfsdmLeftChannel.Init.Awd.FilterOrder          = DFSDM_CHANNEL_SINC1_ORDER;
00816   hAudioIn.hDfsdmLeftChannel.Init.Awd.Oversampling         = 10;
00817   hAudioIn.hDfsdmLeftChannel.Init.Offset                   = 0;
00818   hAudioIn.hDfsdmLeftChannel.Init.RightBitShift            = DFSDMRightBitShift(AudioFreq);
00819 
00820   hAudioIn.hDfsdmLeftChannel.Instance                      = DFSDM_Channel2;
00821 
00822     /* Init the DFSDM Channel */
00823   if (HAL_DFSDM_ChannelInit(&hAudioIn.hDfsdmLeftChannel) != HAL_OK)
00824   {
00825     return AUDIO_ERROR;
00826   }
00827 
00828   /*####FILTER 0####*/
00829   BSP_AUDIO_hDfsdmLeftFilter.Init.RegularParam.Trigger         = DFSDM_FILTER_SW_TRIGGER;
00830   BSP_AUDIO_hDfsdmLeftFilter.Init.RegularParam.FastMode        = ENABLE;
00831   BSP_AUDIO_hDfsdmLeftFilter.Init.RegularParam.DmaMode         = ENABLE;
00832   BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.Trigger        = DFSDM_FILTER_SW_TRIGGER;
00833   BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.ScanMode       = DISABLE;
00834   BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.DmaMode        = DISABLE;
00835   BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.ExtTrigger     = DFSDM_FILTER_EXT_TRIG_TIM8_TRGO;
00836   BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.ExtTriggerEdge = DFSDM_FILTER_EXT_TRIG_BOTH_EDGES;
00837   BSP_AUDIO_hDfsdmLeftFilter.Init.FilterParam.SincOrder        = DFSDMFilterOrder(AudioFreq);
00838   /* Set the DFSDM Filters Oversampling to have correct sample rate */
00839   BSP_AUDIO_hDfsdmLeftFilter.Init.FilterParam.Oversampling     = DFSDMOverSampling(AudioFreq);
00840   BSP_AUDIO_hDfsdmLeftFilter.Init.FilterParam.IntOversampling  = 1;
00841   
00842   BSP_AUDIO_hDfsdmLeftFilter.Instance                          = AUDIO_DFSDMx_LEFT_FILTER;
00843 
00844     /* Init the DFSDM Filter */
00845   if (HAL_DFSDM_FilterInit(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK)
00846   {
00847     return AUDIO_ERROR;
00848   }
00849   
00850   /* Configure regular channel */
00851   if (HAL_DFSDM_FilterConfigRegChannel(&BSP_AUDIO_hDfsdmLeftFilter, 
00852                                       DFSDM_CHANNEL_2, 
00853                                       DFSDM_CONTINUOUS_CONV_ON) != HAL_OK)
00854   {
00855     return AUDIO_ERROR;
00856   }
00857 
00858   return AUDIO_OK;
00859 }
00860 
00861 /**
00862   * @brief  De-initializes the Digital Filter for Sigma-Delta Modulators interface (DFSDM).
00863   * @retval BSP AUDIO status
00864   */
00865 static uint8_t AUDIO_DFSDMx_DeInit(void)
00866 {
00867   /* De-initializes the DFSDM filters to allow access to DFSDM internal registers */
00868   if (HAL_DFSDM_FilterDeInit(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK)
00869   {
00870     return AUDIO_ERROR;
00871   }
00872 
00873   /* De-initializes the DFSDM channels to allow access to DFSDM internal registers */
00874   if (HAL_DFSDM_ChannelDeInit(&hAudioIn.hDfsdmLeftChannel) != HAL_OK)
00875   {
00876     return AUDIO_ERROR;
00877   }
00878 
00879   /* Disable DFSDM clock */
00880   AUDIO_DFSDMx_CLK_DISABLE();
00881 
00882   /* Disable SAIx PLL */
00883   if (AUDIO_SAIx_PLL_DISABLE() != AUDIO_OK)
00884   {
00885     return AUDIO_ERROR;
00886   }  
00887 
00888   /* DFSDM reset */
00889   __HAL_RCC_DFSDM_FORCE_RESET();
00890   __HAL_RCC_DFSDM_RELEASE_RESET();
00891 
00892   return AUDIO_OK;
00893 }
00894 
00895 /**
00896   * @brief  Initializes the DFSDM channel MSP.
00897   * @param  hdfsdm_channel : DFSDM channel handle.
00898   * @retval None
00899   */
00900 void HAL_DFSDM_ChannelMspInit(DFSDM_Channel_HandleTypeDef *hdfsdm_channel)
00901 {
00902   GPIO_InitTypeDef  GPIO_InitStruct;  
00903 
00904   /* Enable DFSDM clock */
00905   AUDIO_DFSDMx_CLK_ENABLE();
00906   
00907   /* Enable GPIO clock */
00908   AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_CLK_ENABLE();
00909   
00910   /* DFSDM pins configuration: DFSDM_CKOUT, DMIC_DATIN pins ------------------*/
00911   GPIO_InitStruct.Pin = AUDIO_DFSDMx_CKOUT_PIN | AUDIO_DFSDMx_DMIC_DATIN_PIN;
00912   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
00913   GPIO_InitStruct.Pull = GPIO_NOPULL;
00914   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
00915   GPIO_InitStruct.Alternate = AUDIO_DFSDMx_CKOUT_DMIC_DATIN_AF;
00916   HAL_GPIO_Init(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, &GPIO_InitStruct);
00917 }
00918 
00919 /**
00920   * @brief  De-initializes the DFSDM channel MSP.
00921   * @param  hdfsdm_channel : DFSDM channel handle.
00922   * @retval None
00923   */
00924 void HAL_DFSDM_ChannelMspDeInit(DFSDM_Channel_HandleTypeDef *hdfsdm_channel)
00925 {
00926   GPIO_InitTypeDef  GPIO_InitStruct;
00927   
00928   /* Enable GPIO clock */
00929   AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_CLK_ENABLE();
00930   
00931   /* DFSDM pins configuration: DFSDM_CKOUT */
00932   GPIO_InitStruct.Pin = AUDIO_DFSDMx_CKOUT_PIN;
00933   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
00934   GPIO_InitStruct.Pull = GPIO_NOPULL;
00935   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
00936   HAL_GPIO_Init(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, &GPIO_InitStruct);
00937   HAL_GPIO_WritePin(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, AUDIO_DFSDMx_CKOUT_PIN, GPIO_PIN_RESET);
00938 
00939 
00940   /* De-initialize DMIC_DATIN pin */
00941   HAL_GPIO_DeInit(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, AUDIO_DFSDMx_DMIC_DATIN_PIN);
00942 }
00943 
00944 /**
00945   * @brief  Initializes the DFSDM filter MSP.
00946   * @param  hdfsdm_filter : DFSDM filter handle.
00947   * @retval None
00948   */
00949 void HAL_DFSDM_FilterMspInit(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
00950 {
00951   /* Enable DFSDM clock */
00952   AUDIO_DFSDMx_CLK_ENABLE();
00953   
00954   /* Enable the DMA clock */
00955   AUDIO_DFSDMx_DMAx_CLK_ENABLE();
00956     
00957   /* Configure the hAudioIn.hDmaDfsdmLeft handle parameters */   
00958   hAudioIn.hDmaDfsdmLeft.Init.Request             = DMA_REQUEST_0;
00959   hAudioIn.hDmaDfsdmLeft.Init.Direction           = DMA_PERIPH_TO_MEMORY;
00960   hAudioIn.hDmaDfsdmLeft.Init.PeriphInc           = DMA_PINC_DISABLE;
00961   hAudioIn.hDmaDfsdmLeft.Init.MemInc              = DMA_MINC_ENABLE;
00962   hAudioIn.hDmaDfsdmLeft.Init.PeriphDataAlignment = AUDIO_DFSDMx_DMAx_PERIPH_DATA_SIZE;
00963   hAudioIn.hDmaDfsdmLeft.Init.MemDataAlignment    = AUDIO_DFSDMx_DMAx_MEM_DATA_SIZE;
00964   hAudioIn.hDmaDfsdmLeft.Init.Mode                = DMA_CIRCULAR;
00965   hAudioIn.hDmaDfsdmLeft.Init.Priority            = DMA_PRIORITY_HIGH;
00966 
00967   hAudioIn.hDmaDfsdmLeft.Instance               = AUDIO_DFSDMx_DMAx_LEFT_CHANNEL;
00968   
00969   /* Associate the DMA handle */
00970   __HAL_LINKDMA(hdfsdm_filter, hdmaReg, hAudioIn.hDmaDfsdmLeft);
00971   
00972   /* Reset DMA handle state */
00973   __HAL_DMA_RESET_HANDLE_STATE(&hAudioIn.hDmaDfsdmLeft);
00974 
00975   /* Configure the DMA Channel */
00976   HAL_DMA_Init(&hAudioIn.hDmaDfsdmLeft);      
00977 
00978   /* DMA IRQ Channel configuration */
00979     HAL_NVIC_SetPriority(AUDIO_DFSDMx_DMAx_LEFT_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0);
00980     HAL_NVIC_EnableIRQ(AUDIO_DFSDMx_DMAx_LEFT_IRQ);
00981   }
00982 
00983  /**
00984   * @brief  De-initializes the DFSDM filter MSP.
00985   * @param  hdfsdm_filter : DFSDM filter handle.
00986   * @retval None
00987   */
00988 void HAL_DFSDM_FilterMspDeInit(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
00989 {
00990   /* Disable DMA  Channel IRQ */
00991   HAL_NVIC_DisableIRQ(AUDIO_DFSDMx_DMAx_LEFT_IRQ);
00992 
00993   /* De-initialize the DMA Channel */
00994   HAL_DMA_DeInit(&hAudioIn.hDmaDfsdmLeft);      
00995 
00996   /* Disable the DMA clock */
00997   AUDIO_DFSDMx_DMAx_CLK_DISABLE();
00998 }
00999 
01000 /**
01001   * @brief  Configures the SAI PLL clock according to the required audio frequency.
01002   * @param  Frequency: Audio frequency.  
01003   * @retval BSP AUDIO status
01004   * @note   The SAI PLL input clock must be configured in the user application.
01005   *         The SAI PLL configuration done within this function assumes that
01006   *         the SAI PLL input clock runs at 8 MHz.
01007   */
01008 static uint8_t AUDIO_SAIPLLConfig(uint32_t Frequency)
01009 {
01010   RCC_PeriphCLKInitTypeDef RCC_ExCLKInitStruct;
01011 
01012   /* Retreive actual RCC configuration */
01013   HAL_RCCEx_GetPeriphCLKConfig(&RCC_ExCLKInitStruct);
01014   
01015     if (   (Frequency == AUDIO_FREQUENCY_11K) 
01016         || (Frequency == AUDIO_FREQUENCY_22K)
01017         || (Frequency == AUDIO_FREQUENCY_44K) )
01018   {
01019     /* Configure PLLSAI prescalers */
01020     /* SAI clock config 
01021     PLLSAI1_VCO= 8 Mhz * PLLSAI1N = 8 * 24 = VCO_192M 
01022     SAI_CK_x = PLLSAI1_VCO/PLLSAI1P = 192/17 = 11.294 Mhz */  
01023     RCC_ExCLKInitStruct.PeriphClockSelection    = RCC_PERIPHCLK_SAI1;
01024     RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1N        = 24; 
01025     RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1P        = 17; 
01026     RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK;
01027     RCC_ExCLKInitStruct.Sai1ClockSelection      = RCC_SAI1CLKSOURCE_PLLSAI1;
01028   }
01029   else /* AUDIO_FREQUENCY_8K, AUDIO_FREQUENCY_16K, AUDIO_FREQUENCY_48K, AUDIO_FREQUENCY_96K */
01030   {
01031     /* SAI clock config 
01032     PLLSAI1_VCO= 8 Mhz * PLLSAI1N = 8 * 43 = VCO_344M 
01033     SAI_CK_x = PLLSAI1_VCO/PLLSAI1P = 344/7 = 49.142 Mhz */  
01034     RCC_ExCLKInitStruct.PeriphClockSelection    = RCC_PERIPHCLK_SAI1;
01035     RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1N        = 43;
01036     RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1P        = 7;
01037     RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK;
01038     RCC_ExCLKInitStruct.Sai1ClockSelection      = RCC_SAI1CLKSOURCE_PLLSAI1;
01039   }
01040   
01041   if (HAL_RCCEx_PeriphCLKConfig(&RCC_ExCLKInitStruct) != HAL_OK)
01042   {
01043     return AUDIO_ERROR;
01044   }    
01045 
01046   return AUDIO_OK;
01047 }
01048 
01049 /**
01050   * @}
01051   */
01052 
01053 /**
01054   * @}
01055   */
01056 
01057 /**
01058   * @}
01059   */
01060 
01061 /**
01062   * @}
01063   */
01064 
01065 /**
01066   * @}
01067   */
01068 
01069 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
01070