STM32Cube BSP FW for STM32F769I-Discovery

Dependents:   mbed-os-example-blinky-5 DISCO-F769NI_TOUCHSCREEN_demo_custom_1 Datarecorder2 DISCO-F769NI_TOUCHSCREEN_demo ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32f769i_discovery_audio.c Source File

stm32f769i_discovery_audio.c

Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f769i_discovery_audio.c
00004   * @author  MCD Application Team
00005   * @brief   This file provides the Audio driver for the STM32F769I-DISCOVERY  
00006   *          board.
00007   @verbatim
00008   How To use this driver:
00009   -----------------------
00010    + This driver supports STM32F7xx devices on STM32F769I-DISCOVERY (MB1225) Evaluation boards.
00011    + Call the function BSP_AUDIO_OUT_Init(
00012                                     OutputDevice: physical output mode (OUTPUT_DEVICE_SPEAKER, 
00013                                                   OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH)
00014                                     Volume      : Initial volume to be set (0 is min (mute), 100 is max (100%)
00015                                     AudioFreq   : Audio frequency in Hz (8000, 16000, 22500, 32000...)
00016                                                   this parameter is relative to the audio file/stream type.
00017                                    )
00018       This function configures all the hardware required for the audio application (codec, I2C, SAI, 
00019       GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if configuration is OK.
00020       If the returned value is different from AUDIO_OK or the function is stuck then the communication with
00021       the codec has failed (try to un-plug the power or reset device in this case).
00022       - OUTPUT_DEVICE_SPEAKER  : only speaker will be set as output for the audio stream.
00023       - OUTPUT_DEVICE_HEADPHONE: only headphones will be set as output for the audio stream.
00024       - OUTPUT_DEVICE_BOTH     : both Speaker and Headphone are used as outputs for the audio stream
00025                                  at the same time.
00026       Note. On STM32F769I-DISCOVERY SAI_DMA is configured in CIRCULAR mode. Due to this the application
00027         does NOT need to call BSP_AUDIO_OUT_ChangeBuffer() to assure streaming.
00028    + Call the function BSP_AUDIO_OUT_Play(
00029                                   pBuffer: pointer to the audio data file address
00030                                   Size   : size of the buffer to be sent in Bytes
00031                                  )
00032       to start playing (for the first time) from the audio file/stream.
00033    + Call the function BSP_AUDIO_OUT_Pause() to pause playing   
00034    + Call the function BSP_AUDIO_OUT_Resume() to resume playing.
00035        Note. After calling BSP_AUDIO_OUT_Pause() function for pause, only BSP_AUDIO_OUT_Resume() should be called
00036           for resume (it is not allowed to call BSP_AUDIO_OUT_Play() in this case).
00037        Note. This function should be called only when the audio file is played or paused (not stopped).
00038    + For each mode, you may need to implement the relative callback functions into your code.
00039       The Callback functions are named BSP_AUDIO_OUT_XXX_CallBack() and only their prototypes are declared in 
00040       the stm32f769i_discovery_audio.h file. (refer to the example for more details on the callbacks implementations)
00041    + To Stop playing, to modify the volume level, the frequency, the audio frame slot, 
00042       the device output mode the mute or the stop, use the functions: BSP_AUDIO_OUT_SetVolume(), 
00043       AUDIO_OUT_SetFrequency(), BSP_AUDIO_OUT_SetAudioFrameSlot(), BSP_AUDIO_OUT_SetOutputMode(),
00044       BSP_AUDIO_OUT_SetMute() and BSP_AUDIO_OUT_Stop().
00045 
00046    + Call the function BSP_AUDIO_IN_Init(
00047                                     AudioFreq: Audio frequency in Hz (8000, 16000, 22500, 32000...)
00048                                                   this parameter is relative to the audio file/stream type.
00049                                     BitRes: Bit resolution fixed to 16bit
00050                                     ChnlNbr: Number of channel to be configured for the DFSDM peripheral
00051                                    )
00052       This function configures all the hardware required for the audio in application (DFSDM filters and channels, 
00053       Clock source for DFSDM periphiral, GPIOs, DMA and interrupt if needed). 
00054       This function returns AUDIO_OK if configuration is OK.If the returned value is different from AUDIO_OK then
00055       the configuration should be wrong.
00056       Note: On STM32F769I-DISCOVERY, four DFSDM Channel/Filters are configured and their DMA streams are configured
00057             in CIRCULAR mode.
00058    + Call the function BSP_AUDIO_IN_AllocScratch(
00059                                         pScratch: pointer to scratch tables
00060                                         size: size of scratch buffer)
00061      This function must be called before BSP_AUDIO_IN_RECORD() to allocate buffer scratch for each DFSDM channel
00062      and its size.
00063      Note: These buffers scratch are used as intermidiate buffers to collect data within final record buffer.
00064            size is the total size of the four buffers scratch; If size is 512 then the size of each is 128.
00065            This function must be called after BSP_AUDIO_IN_Init()
00066    + Call the function BSP_AUDIO_IN_RECORD(
00067                                   pBuf: pointer to the recorded audio data file address
00068                                   Size: size of the buffer to be written in Bytes
00069                                  )
00070       to start recording from microphones.
00071 
00072    + Call the function BSP_AUDIO_IN_Pause() to pause recording   
00073    + Call the function BSP_AUDIO_IN_Resume() to recording playing.
00074        Note. After calling BSP_AUDIO_IN_Pause() function for pause, only BSP_AUDIO_IN_Resume() should be called
00075           for resume (it is not allowed to call BSP_AUDIO_IN_RECORD() in this case).
00076    + Call the function BSP_AUDIO_IN_Stop() to stop recording 
00077    + For each mode, you may need to implement the relative callback functions into your code.
00078       The Callback functions are named BSP_AUDIO_IN_XXX_CallBack() and only their prototypes are declared in 
00079       the stm32f769i_discovery_audio.h file. (refer to the example for more details on the callbacks implementations)
00080 
00081   Driver architecture:
00082   --------------------
00083    + This driver provides the High Audio Layer: consists of the function API exported in the stm32f769i_discovery_audio.h file
00084      (BSP_AUDIO_OUT_Init(), BSP_AUDIO_OUT_Play() ...)
00085    + This driver provide also the Media Access Layer (MAL): which consists of functions allowing to access the media containing/
00086      providing the audio file/stream. These functions are also included as local functions into
00087      the stm32f769i_discovery_audio.c file (DFSDMx_Init(), DFSDMx_DeInit(), SAIx_Init() and SAIx_DeInit())
00088 
00089   Known Limitations:
00090   ------------------
00091    1- If the TDM Format used to play in parallel 2 audio Stream (the first Stream is configured in codec SLOT0 and second 
00092       Stream in SLOT1) the Pause/Resume, volume and mute feature will control the both streams.
00093    2- Parsing of audio file is not implemented (in order to determine audio file properties: Mono/Stereo, Data size, 
00094       File size, Audio Frequency, Audio Data header size ...). The configuration is fixed for the given audio file.
00095    3- Supports only Stereo audio streaming.
00096    4- Supports only 16-bits audio data size.
00097   @endverbatim  
00098   ******************************************************************************
00099   * @attention
00100   *
00101   * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
00102   *
00103   * Redistribution and use in source and binary forms, with or without modification,
00104   * are permitted provided that the following conditions are met:
00105   *   1. Redistributions of source code must retain the above copyright notice,
00106   *      this list of conditions and the following disclaimer.
00107   *   2. Redistributions in binary form must reproduce the above copyright notice,
00108   *      this list of conditions and the following disclaimer in the documentation
00109   *      and/or other materials provided with the distribution.
00110   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00111   *      may be used to endorse or promote products derived from this software
00112   *      without specific prior written permission.
00113   *
00114   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00115   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00116   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00117   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00118   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00119   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00120   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00121   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00122   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00123   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00124   *
00125   ******************************************************************************
00126   */
00127 
00128 /* Dependencies
00129 - stm32f769i_discovery.c
00130 - stm32f7xx_hal_sai.c
00131 - stm32f7xx_hal_dfsdm.c
00132 - stm32f7xx_hal_dma.c
00133 - stm32f7xx_hal_gpio.c
00134 - stm32f7xx_hal_cortex.c
00135 - stm32f7xx_hal_rcc_ex.h
00136 - wm8994.c
00137 EndDependencies */
00138 
00139 /* Includes ------------------------------------------------------------------*/
00140 #include "stm32f769i_discovery_audio.h"
00141 
00142 /** @addtogroup BSP
00143   * @{
00144   */
00145 
00146 /** @addtogroup STM32F769I_DISCOVERY
00147   * @{
00148   */ 
00149   
00150 /** @defgroup STM32F769I_DISCOVERY_AUDIO STM32F769I_DISCOVERY AUDIO
00151   * @brief This file includes the low layer driver for wm8994 Audio Codec
00152   *        available on STM32F769I-DISCOVERY discoveryuation board(MB1225).
00153   * @{
00154   */ 
00155 
00156 /** @defgroup STM32F769I_DISCOVERY_AUDIO_Private_Types STM32F769I_DISCOVERY_AUDIO Private Types
00157   * @{
00158   */ 
00159 typedef struct
00160 {
00161   uint16_t      *pRecBuf;       /* Pointer to record user buffer */
00162   uint32_t      RecSize;        /* Size to record in mono, double size to record in stereo */
00163 }AUDIOIN_TypeDef;
00164 
00165 /**
00166   * @}
00167   */ 
00168   
00169 /** @defgroup STM32F769I_DISCOVERY_AUDIO_Private_Defines STM32F769I_DISCOVERY_AUDIO Private Defines
00170   * @{
00171   */
00172 /**
00173   * @}
00174   */ 
00175 
00176 /** @defgroup STM32F769I_DISCOVERY_AUDIO_Private_Macros STM32F769I_DISCOVERY_AUDIO Private Macros
00177   * @{
00178   */
00179 /*### RECORD ###*/
00180 #define DFSDM_OVER_SAMPLING(__FREQUENCY__) \
00181         (__FREQUENCY__ == AUDIO_FREQUENCY_8K)  ? 256 \
00182       : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 256 \
00183       : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 128 \
00184       : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 128 \
00185       : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 64 \
00186       : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 64  \
00187       : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 40 : 20  \
00188 
00189 #define DFSDM_CLOCK_DIVIDER(__FREQUENCY__) \
00190         (__FREQUENCY__ == AUDIO_FREQUENCY_8K)  ? 24 \
00191       : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 4 \
00192       : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 24 \
00193       : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 4 \
00194       : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 24 \
00195       : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 4  \
00196       : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 25 : 25  \
00197 
00198 #define DFSDM_FILTER_ORDER(__FREQUENCY__) \
00199         (__FREQUENCY__ == AUDIO_FREQUENCY_8K)  ? DFSDM_FILTER_SINC3_ORDER \
00200       : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? DFSDM_FILTER_SINC3_ORDER \
00201       : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? DFSDM_FILTER_SINC3_ORDER \
00202       : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? DFSDM_FILTER_SINC3_ORDER \
00203       : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? DFSDM_FILTER_SINC4_ORDER \
00204       : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? DFSDM_FILTER_SINC3_ORDER  \
00205       : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? DFSDM_FILTER_SINC3_ORDER : DFSDM_FILTER_SINC5_ORDER  \
00206 
00207 #define DFSDM_RIGHT_BIT_SHIFT(__FREQUENCY__) \
00208         (__FREQUENCY__ == AUDIO_FREQUENCY_8K)  ? 8 \
00209       : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 8 \
00210       : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 3 \
00211       : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 4 \
00212       : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 7 \
00213       : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 0  \
00214       : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 0 : 4  \
00215 
00216 /* Saturate the record PCM sample */
00217 #define SaturaLH(N, L, H) (((N)<(L))?(L):(((N)>(H))?(H):(N)))
00218 /**
00219   * @}
00220   */ 
00221   
00222 /** @defgroup STM32F769I_DISCOVERY_AUDIO_Private_Variables STM32F769I_DISCOVERY_AUDIO Private Variables
00223   * @{
00224   */
00225 /* PLAY */
00226 AUDIO_DrvTypeDef                *audio_drv;
00227 SAI_HandleTypeDef               haudio_out_sai;
00228 SAI_HandleTypeDef               haudio_in_sai;
00229 
00230 /* RECORD */
00231 AUDIOIN_TypeDef                 hAudioIn;
00232 
00233 DFSDM_Channel_HandleTypeDef     hAudioInTopLeftChannel;
00234 DFSDM_Channel_HandleTypeDef     hAudioInTopRightChannel;
00235 DFSDM_Filter_HandleTypeDef      hAudioInTopLeftFilter;
00236 DFSDM_Filter_HandleTypeDef      hAudioInTopRightFilter;
00237 DMA_HandleTypeDef               hDmaTopLeft;
00238 DMA_HandleTypeDef               hDmaTopRight;
00239 
00240 DFSDM_Channel_HandleTypeDef     hAudioInButtomLeftChannel;
00241 DFSDM_Channel_HandleTypeDef     hAudioInButtomRightChannel;
00242 DFSDM_Filter_HandleTypeDef      hAudioInButtomLeftFilter;
00243 DFSDM_Filter_HandleTypeDef      hAudioInButtomRightFilter;
00244 DMA_HandleTypeDef               hDmaButtomLeft;
00245 DMA_HandleTypeDef               hDmaButtomRight;
00246 
00247 /* Buffers for right and left samples */
00248 static int32_t                  *pScratchBuff[2*DEFAULT_AUDIO_IN_CHANNEL_NBR];
00249 static __IO int32_t             ScratchSize;
00250 /* Cannel number to be used: 2 channels by default */
00251 static uint8_t                  AudioIn_ChannelNumber = DEFAULT_AUDIO_IN_CHANNEL_NBR;
00252 /* Input device to be used: digital microphones by default */
00253 static uint16_t                 AudioIn_Device = INPUT_DEVICE_DIGITAL_MIC; 
00254 
00255 /* Buffers status flags */
00256 static uint32_t                DmaTopLeftRecHalfCplt  = 0;
00257 static uint32_t                DmaTopLeftRecCplt      = 0;
00258 static uint32_t                DmaTopRightRecHalfCplt = 0;
00259 static uint32_t                DmaTopRightRecCplt     = 0;
00260 static uint32_t                DmaButtomLeftRecHalfCplt  = 0;
00261 static uint32_t                DmaButtomLeftRecCplt      = 0;
00262 static uint32_t                DmaButtomRightRecHalfCplt = 0;
00263 static uint32_t                DmaButtomRightRecCplt     = 0;
00264 
00265 /* Application Buffer Trigger */
00266 static __IO uint32_t           AppBuffTrigger          = 0;
00267 static __IO uint32_t           AppBuffHalf             = 0;
00268 
00269 /**
00270   * @}
00271   */ 
00272 
00273 /** @defgroup STM32F769I_DISCOVERY_AUDIO_Private_Function_Prototypes STM32F769I_DISCOVERY_AUDIO Private Function Prototypes
00274   * @{
00275   */
00276 static void SAIx_Out_Init(uint32_t AudioFreq);
00277 static void SAIx_Out_DeInit(void);
00278 static void SAI_AUDIO_IN_MspInit(SAI_HandleTypeDef *hsai, void *Params);
00279 static void SAI_AUDIO_IN_MspDeInit(SAI_HandleTypeDef *hsai, void *Params);
00280 static void SAIx_In_Init(uint32_t AudioFreq);
00281 static void SAIx_In_DeInit(void);
00282 static void    DFSDMx_ChannelMspInit(void);
00283 static void    DFSDMx_FilterMspInit(void);
00284 static void    DFSDMx_ChannelMspDeInit(void);
00285 static void    DFSDMx_FilterMspDeInit(void);
00286 static uint8_t DFSDMx_Init(uint32_t AudioFreq);
00287 static uint8_t DFSDMx_DeInit(void);
00288 
00289 /**
00290   * @}
00291   */ 
00292 
00293 /** @defgroup STM32F769I_DISCOVERY_AUDIO_out_Private_Functions STM32F769I_DISCOVERY_AUDIO_Out Private Functions
00294   * @{
00295   */ 
00296 
00297 /**
00298   * @brief  Configures the audio peripherals.
00299   * @param  OutputDevice: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
00300   *                       or OUTPUT_DEVICE_BOTH.
00301   * @param  Volume: Initial volume level (from 0 (Mute) to 100 (Max))
00302   * @param  AudioFreq: Audio frequency used to play the audio stream.  
00303   * @retval AUDIO_OK if correct communication, else wrong communication
00304   */
00305 uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq)
00306 { 
00307   uint8_t ret = AUDIO_ERROR;
00308   uint32_t deviceid = 0x00;
00309 
00310   /* Disable SAI */
00311   SAIx_Out_DeInit();
00312 
00313   /* PLL clock is set depending by the AudioFreq (44.1khz vs 48khz groups) */ 
00314   BSP_AUDIO_OUT_ClockConfig(&haudio_out_sai, AudioFreq, NULL);
00315  
00316   /* SAI data transfer preparation:
00317   Prepare the Media to be used for the audio transfer from memory to SAI peripheral */
00318   haudio_out_sai.Instance = AUDIO_OUT_SAIx;
00319   if(HAL_SAI_GetState(&haudio_out_sai) == HAL_SAI_STATE_RESET)
00320   {
00321     /* Init the SAI MSP: this __weak function can be redefined by the application*/
00322     BSP_AUDIO_OUT_MspInit(&haudio_out_sai, NULL);
00323   }
00324   SAIx_Out_Init(AudioFreq);
00325 
00326   /* wm8994 codec initialization */
00327   deviceid = wm8994_drv.ReadID(AUDIO_I2C_ADDRESS);
00328   
00329   if((deviceid) == WM8994_ID)
00330   {  
00331     /* Reset the Codec Registers */
00332     wm8994_drv.Reset(AUDIO_I2C_ADDRESS);
00333     /* Initialize the audio driver structure */
00334     audio_drv = &wm8994_drv; 
00335     ret = AUDIO_OK;
00336   }
00337   else
00338   {
00339     ret = AUDIO_ERROR;
00340   }
00341 
00342   if(ret == AUDIO_OK)
00343   {
00344     /* Initialize the codec internal registers */
00345     audio_drv->Init(AUDIO_I2C_ADDRESS, OutputDevice, Volume, AudioFreq);
00346   }
00347  
00348   return ret;
00349 }
00350 
00351 /**
00352   * @brief  Starts playing audio stream from a data buffer for a determined size. 
00353   * @param  pBuffer: Pointer to the buffer 
00354   * @param  Size: Number of audio data BYTES.
00355   * @retval AUDIO_OK if correct communication, else wrong communication
00356   */
00357 uint8_t BSP_AUDIO_OUT_Play(uint16_t* pBuffer, uint32_t Size)
00358 {
00359   /* Call the audio Codec Play function */
00360   if(audio_drv->Play(AUDIO_I2C_ADDRESS, (uint16_t *)pBuffer, Size) != 0)
00361   {  
00362     return AUDIO_ERROR;
00363   }
00364   else
00365   {
00366     /* Update the Media layer and enable it for play */  
00367     HAL_SAI_Transmit_DMA(&haudio_out_sai, (uint8_t*) pBuffer, DMA_MAX(Size / AUDIODATA_SIZE));
00368     
00369     return AUDIO_OK;
00370   }
00371 }
00372 
00373 /**
00374   * @brief  Sends n-Bytes on the SAI interface.
00375   * @param  pData: pointer on data address 
00376   * @param  Size: number of data to be written
00377   * @retval None
00378   */
00379 void BSP_AUDIO_OUT_ChangeBuffer(uint16_t *pData, uint16_t Size)
00380 {
00381    HAL_SAI_Transmit_DMA(&haudio_out_sai, (uint8_t*) pData, Size);
00382 }
00383 
00384 /**
00385   * @brief  This function Pauses the audio file stream. In case
00386   *         of using DMA, the DMA Pause feature is used.
00387   * @note    When calling BSP_AUDIO_OUT_Pause() function for pause, only
00388   *          BSP_AUDIO_OUT_Resume() function should be called for resume (use of BSP_AUDIO_OUT_Play() 
00389   *          function for resume could lead to unexpected behaviour).
00390   * @retval AUDIO_OK if correct communication, else wrong communication
00391   */
00392 uint8_t BSP_AUDIO_OUT_Pause(void)
00393 {    
00394   /* Call the Audio Codec Pause/Resume function */
00395   if(audio_drv->Pause(AUDIO_I2C_ADDRESS) != 0)
00396   {
00397     return AUDIO_ERROR;
00398   }
00399   else
00400   {
00401     /* Call the Media layer pause function */
00402     HAL_SAI_DMAPause(&haudio_out_sai);
00403     
00404     /* Return AUDIO_OK when all operations are correctly done */
00405     return AUDIO_OK;
00406   }
00407 }
00408 
00409 /**
00410   * @brief   Resumes the audio file stream.  
00411   * @note    When calling BSP_AUDIO_OUT_Pause() function for pause, only
00412   *          BSP_AUDIO_OUT_Resume() function should be called for resume (use of BSP_AUDIO_OUT_Play() 
00413   *          function for resume could lead to unexpected behaviour).
00414   * @retval AUDIO_OK if correct communication, else wrong communication
00415   */
00416 uint8_t BSP_AUDIO_OUT_Resume(void)
00417 {    
00418   /* Call the Audio Codec Pause/Resume function */
00419   if(audio_drv->Resume(AUDIO_I2C_ADDRESS) != 0)
00420   {
00421     return AUDIO_ERROR;
00422   }
00423   else
00424   {
00425     /* Call the Media layer pause/resume function */
00426     HAL_SAI_DMAResume(&haudio_out_sai);
00427     
00428     /* Return AUDIO_OK when all operations are correctly done */
00429     return AUDIO_OK;
00430   }
00431 }
00432 
00433 /**
00434   * @brief  Stops audio playing and Power down the Audio Codec. 
00435   * @param  Option: could be one of the following parameters 
00436   *           - CODEC_PDWN_SW: for software power off (by writing registers). 
00437   *                            Then no need to reconfigure the Codec after power on.
00438   *           - CODEC_PDWN_HW: completely shut down the codec (physically). 
00439   *                            Then need to reconfigure the Codec after power on.  
00440   * @retval AUDIO_OK if correct communication, else wrong communication
00441   */
00442 uint8_t BSP_AUDIO_OUT_Stop(uint32_t Option)
00443 {
00444   /* Call the Media layer stop function */
00445   HAL_SAI_DMAStop(&haudio_out_sai);
00446   
00447   /* Call Audio Codec Stop function */
00448   if(audio_drv->Stop(AUDIO_I2C_ADDRESS, Option) != 0)
00449   {
00450     return AUDIO_ERROR;
00451   }
00452   else
00453   {
00454     if(Option == CODEC_PDWN_HW)
00455     { 
00456       /* Wait at least 100us */
00457       HAL_Delay(1);
00458     }
00459     /* Return AUDIO_OK when all operations are correctly done */
00460     return AUDIO_OK;
00461   }
00462 }
00463 
00464 /**
00465   * @brief  Controls the current audio volume level. 
00466   * @param  Volume: Volume level to be set in percentage from 0% to 100% (0 for 
00467   *         Mute and 100 for Max volume level).
00468   * @retval AUDIO_OK if correct communication, else wrong communication
00469   */
00470 uint8_t BSP_AUDIO_OUT_SetVolume(uint8_t Volume)
00471 {
00472   /* Call the codec volume control function with converted volume value */
00473   if(audio_drv->SetVolume(AUDIO_I2C_ADDRESS, Volume) != 0)
00474   {
00475     return AUDIO_ERROR;
00476   }
00477   else
00478   {
00479     /* Return AUDIO_OK when all operations are correctly done */
00480     return AUDIO_OK;
00481   }
00482 }
00483 
00484 /**
00485   * @brief  Enables or disables the MUTE mode by software 
00486   * @param  Cmd: Could be AUDIO_MUTE_ON to mute sound or AUDIO_MUTE_OFF to 
00487   *         unmute the codec and restore previous volume level.
00488   * @retval AUDIO_OK if correct communication, else wrong communication
00489   */
00490 uint8_t BSP_AUDIO_OUT_SetMute(uint32_t Cmd)
00491 { 
00492   /* Call the Codec Mute function */
00493   if(audio_drv->SetMute(AUDIO_I2C_ADDRESS, Cmd) != 0)
00494   {
00495     return AUDIO_ERROR;
00496   }
00497   else
00498   {
00499     /* Return AUDIO_OK when all operations are correctly done */
00500     return AUDIO_OK;
00501   }
00502 }
00503 
00504 /**
00505   * @brief  Switch dynamically (while audio file is played) the output target 
00506   *         (speaker or headphone).
00507   * @param  Output: The audio output target: OUTPUT_DEVICE_SPEAKER,
00508   *         OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH
00509   * @retval AUDIO_OK if correct communication, else wrong communication
00510   */
00511 uint8_t BSP_AUDIO_OUT_SetOutputMode(uint8_t Output)
00512 {
00513   /* Call the Codec output device function */
00514   if(audio_drv->SetOutputMode(AUDIO_I2C_ADDRESS, Output) != 0)
00515   {
00516     return AUDIO_ERROR;
00517   }
00518   else
00519   {
00520     /* Return AUDIO_OK when all operations are correctly done */
00521     return AUDIO_OK;
00522   }
00523 }
00524 
00525 /**
00526   * @brief  Updates the audio frequency.
00527   * @param  AudioFreq: Audio frequency used to play the audio stream.
00528   * @note   This API should be called after the BSP_AUDIO_OUT_Init() to adjust the
00529   *         audio frequency.
00530   * @retval None
00531   */
00532 void BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq)
00533 { 
00534   /* PLL clock is set depending by the AudioFreq (44.1khz vs 48khz groups) */ 
00535   BSP_AUDIO_OUT_ClockConfig(&haudio_out_sai, AudioFreq, NULL);
00536 
00537   /* Disable SAI peripheral to allow access to SAI internal registers */
00538   __HAL_SAI_DISABLE(&haudio_out_sai);
00539   
00540   /* Update the SAI audio frequency configuration */
00541   haudio_out_sai.Init.AudioFrequency = AudioFreq;
00542   HAL_SAI_Init(&haudio_out_sai);
00543   
00544   /* Enable SAI peripheral to generate MCLK */
00545   __HAL_SAI_ENABLE(&haudio_out_sai);
00546 }
00547 
00548 /**
00549   * @brief  Updates the Audio frame slot configuration.
00550   * @param  AudioFrameSlot: specifies the audio Frame slot
00551   * @note   This API should be called after the BSP_AUDIO_OUT_Init() to adjust the
00552   *         audio frame slot.
00553   * @retval None
00554   */
00555 void BSP_AUDIO_OUT_SetAudioFrameSlot(uint32_t AudioFrameSlot)
00556 { 
00557   /* Disable SAI peripheral to allow access to SAI internal registers */
00558   __HAL_SAI_DISABLE(&haudio_out_sai);
00559   
00560   /* Update the SAI audio frame slot configuration */
00561   haudio_out_sai.SlotInit.SlotActive = AudioFrameSlot;
00562   HAL_SAI_Init(&haudio_out_sai);
00563   
00564   /* Enable SAI peripheral to generate MCLK */
00565   __HAL_SAI_ENABLE(&haudio_out_sai);
00566 }
00567                         
00568 /**
00569   * @brief  De-initializes the audio out peripheral.
00570   * @retval None
00571   */
00572 void BSP_AUDIO_OUT_DeInit(void)
00573 {
00574   SAIx_Out_DeInit();
00575   /* DeInit the SAI MSP : this __weak function can be rewritten by the application */
00576   BSP_AUDIO_OUT_MspDeInit(&haudio_out_sai, NULL);
00577 }
00578 
00579 /**
00580   * @brief  Tx Transfer completed callbacks.
00581   * @param  hsai: SAI handle
00582   * @retval None
00583   */
00584 void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
00585 {
00586   /* Manage the remaining file size and new address offset: This function 
00587      should be coded by user (its prototype is already declared in stm32f769i_discovery_audio.h) */
00588   BSP_AUDIO_OUT_TransferComplete_CallBack();
00589 }
00590 
00591 /**
00592   * @brief  Tx Half Transfer completed callbacks.
00593   * @param  hsai: SAI handle
00594   * @retval None
00595   */
00596 void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
00597 {
00598   /* Manage the remaining file size and new address offset: This function 
00599      should be coded by user (its prototype is already declared in stm32f769i_discovery_audio.h) */
00600   BSP_AUDIO_OUT_HalfTransfer_CallBack();
00601 }
00602 
00603 /**
00604   * @brief  SAI error callbacks.
00605   * @param  hsai: SAI handle
00606   * @retval None
00607   */
00608 void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai)
00609 {
00610   if(hsai->Instance == AUDIO_OUT_SAIx)
00611   {
00612   BSP_AUDIO_OUT_Error_CallBack();
00613   }
00614   else
00615   {
00616     BSP_AUDIO_IN_Error_CallBack();
00617   }
00618 }
00619 
00620 /**
00621   * @brief  Manages the DMA full Transfer complete event.
00622   * @retval None
00623   */
00624 __weak void BSP_AUDIO_OUT_TransferComplete_CallBack(void)
00625 {
00626 }
00627 
00628 /**
00629   * @brief  Manages the DMA Half Transfer complete event.
00630   * @retval None
00631   */
00632 __weak void BSP_AUDIO_OUT_HalfTransfer_CallBack(void)
00633 { 
00634 }
00635 
00636 /**
00637   * @brief  Manages the DMA FIFO error event.
00638   * @retval None
00639   */
00640 __weak void BSP_AUDIO_OUT_Error_CallBack(void)
00641 {
00642 }
00643 
00644 /**
00645   * @brief  Initializes BSP_AUDIO_OUT MSP.
00646   * @param  hsai: SAI handle
00647   * @param  Params  
00648   * @retval None
00649   */
00650 __weak void BSP_AUDIO_OUT_MspInit(SAI_HandleTypeDef *hsai, void *Params)
00651 { 
00652   static DMA_HandleTypeDef hdma_sai_tx;
00653   GPIO_InitTypeDef  gpio_init_structure;  
00654   
00655   /* Enable SAI clock */
00656   AUDIO_OUT_SAIx_CLK_ENABLE();
00657   
00658   
00659   /* Enable GPIO clock */
00660   AUDIO_OUT_SAIx_MCLK_ENABLE();
00661   AUDIO_OUT_SAIx_SD_FS_CLK_ENABLE();
00662   
00663   /* CODEC_SAI pins configuration: FS, SCK, MCK and SD pins ------------------*/
00664   gpio_init_structure.Pin = AUDIO_OUT_SAIx_FS_PIN | AUDIO_OUT_SAIx_SCK_PIN | AUDIO_OUT_SAIx_SD_PIN;
00665   gpio_init_structure.Mode = GPIO_MODE_AF_PP;
00666   gpio_init_structure.Pull = GPIO_NOPULL;
00667   gpio_init_structure.Speed = GPIO_SPEED_HIGH;
00668   gpio_init_structure.Alternate = AUDIO_OUT_SAIx_AF;
00669   HAL_GPIO_Init(AUDIO_OUT_SAIx_SD_FS_SCK_GPIO_PORT, &gpio_init_structure);
00670   
00671   gpio_init_structure.Pin = AUDIO_OUT_SAIx_MCLK_PIN;
00672   HAL_GPIO_Init(AUDIO_OUT_SAIx_MCLK_GPIO_PORT, &gpio_init_structure);
00673   
00674   /* Enable the DMA clock */
00675   AUDIO_OUT_SAIx_DMAx_CLK_ENABLE();
00676   
00677   if(hsai->Instance == AUDIO_OUT_SAIx)
00678   {
00679     /* Configure the hdma_saiTx handle parameters */   
00680     hdma_sai_tx.Init.Channel             = AUDIO_OUT_SAIx_DMAx_CHANNEL;
00681     hdma_sai_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
00682     hdma_sai_tx.Init.PeriphInc           = DMA_PINC_DISABLE;
00683     hdma_sai_tx.Init.MemInc              = DMA_MINC_ENABLE;
00684     hdma_sai_tx.Init.PeriphDataAlignment = AUDIO_OUT_SAIx_DMAx_PERIPH_DATA_SIZE;
00685     hdma_sai_tx.Init.MemDataAlignment    = AUDIO_OUT_SAIx_DMAx_MEM_DATA_SIZE;
00686     hdma_sai_tx.Init.Mode                = DMA_CIRCULAR;
00687     hdma_sai_tx.Init.Priority            = DMA_PRIORITY_HIGH;
00688     hdma_sai_tx.Init.FIFOMode            = DMA_FIFOMODE_ENABLE;         
00689     hdma_sai_tx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
00690     hdma_sai_tx.Init.MemBurst            = DMA_MBURST_SINGLE;
00691     hdma_sai_tx.Init.PeriphBurst         = DMA_PBURST_SINGLE; 
00692     
00693     hdma_sai_tx.Instance = AUDIO_OUT_SAIx_DMAx_STREAM;
00694     
00695     /* Associate the DMA handle */
00696     __HAL_LINKDMA(hsai, hdmatx, hdma_sai_tx);
00697     
00698     /* Deinitialize the Stream for new transfer */
00699     HAL_DMA_DeInit(&hdma_sai_tx);
00700     
00701     /* Configure the DMA Stream */
00702     HAL_DMA_Init(&hdma_sai_tx);
00703   }
00704   
00705   /* SAI DMA IRQ Channel configuration */
00706   HAL_NVIC_SetPriority(AUDIO_OUT_SAIx_DMAx_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0);
00707   HAL_NVIC_EnableIRQ(AUDIO_OUT_SAIx_DMAx_IRQ);
00708 }
00709 
00710 /**
00711   * @brief  Initializes SAI Audio IN MSP.
00712   * @param  hsai: SAI handle
00713   * @param  Params  
00714   * @retval None
00715   */
00716 static void SAI_AUDIO_IN_MspInit(SAI_HandleTypeDef *hsai, void *Params)
00717 {
00718   static DMA_HandleTypeDef hdma_sai_rx;
00719   GPIO_InitTypeDef  gpio_init_structure;  
00720 
00721   /* Enable SAI clock */
00722   AUDIO_IN_SAIx_CLK_ENABLE();
00723   
00724   /* Enable SD GPIO clock */
00725   AUDIO_IN_SAIx_SD_ENABLE();
00726   /* CODEC_SAI pin configuration: SD pin */
00727   gpio_init_structure.Pin = AUDIO_IN_SAIx_SD_PIN;
00728   gpio_init_structure.Mode = GPIO_MODE_AF_PP;
00729   gpio_init_structure.Pull = GPIO_NOPULL;
00730   gpio_init_structure.Speed = GPIO_SPEED_FAST;
00731   gpio_init_structure.Alternate = AUDIO_IN_SAIx_AF;
00732   HAL_GPIO_Init(AUDIO_IN_SAIx_SD_GPIO_PORT, &gpio_init_structure);
00733 
00734   /* Enable Audio INT GPIO clock */
00735   AUDIO_IN_INT_GPIO_ENABLE();
00736   /* Audio INT pin configuration: input */
00737   gpio_init_structure.Pin = AUDIO_IN_INT_GPIO_PIN;
00738   gpio_init_structure.Mode = GPIO_MODE_INPUT;
00739   gpio_init_structure.Pull = GPIO_NOPULL;
00740   gpio_init_structure.Speed = GPIO_SPEED_FAST;
00741   HAL_GPIO_Init(AUDIO_IN_INT_GPIO_PORT, &gpio_init_structure);
00742 
00743   /* Enable the DMA clock */
00744   AUDIO_IN_SAIx_DMAx_CLK_ENABLE();
00745     
00746   if(hsai->Instance == AUDIO_IN_SAIx)
00747   {
00748     /* Configure the hdma_sai_rx handle parameters */
00749     hdma_sai_rx.Init.Channel             = AUDIO_IN_SAIx_DMAx_CHANNEL;
00750     hdma_sai_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;
00751     hdma_sai_rx.Init.PeriphInc           = DMA_PINC_DISABLE;
00752     hdma_sai_rx.Init.MemInc              = DMA_MINC_ENABLE;
00753     hdma_sai_rx.Init.PeriphDataAlignment = AUDIO_IN_SAIx_DMAx_PERIPH_DATA_SIZE;
00754     hdma_sai_rx.Init.MemDataAlignment    = AUDIO_IN_SAIx_DMAx_MEM_DATA_SIZE;
00755     hdma_sai_rx.Init.Mode                = DMA_CIRCULAR;
00756     hdma_sai_rx.Init.Priority            = DMA_PRIORITY_HIGH;
00757     hdma_sai_rx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
00758     hdma_sai_rx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
00759     hdma_sai_rx.Init.MemBurst            = DMA_MBURST_SINGLE;
00760     hdma_sai_rx.Init.PeriphBurst         = DMA_MBURST_SINGLE;
00761     
00762     hdma_sai_rx.Instance = AUDIO_IN_SAIx_DMAx_STREAM;
00763     
00764     /* Associate the DMA handle */
00765     __HAL_LINKDMA(hsai, hdmarx, hdma_sai_rx);
00766     
00767     /* Deinitialize the Stream for new transfer */
00768     HAL_DMA_DeInit(&hdma_sai_rx);
00769     
00770     /* Configure the DMA Stream */
00771     HAL_DMA_Init(&hdma_sai_rx);
00772   }
00773   
00774   /* SAI DMA IRQ Channel configuration */
00775   HAL_NVIC_SetPriority(AUDIO_IN_SAIx_DMAx_IRQ, AUDIO_IN_IRQ_PREPRIO, 0);
00776   HAL_NVIC_EnableIRQ(AUDIO_IN_SAIx_DMAx_IRQ);
00777 
00778   /* Audio INT IRQ Channel configuration */
00779   HAL_NVIC_SetPriority(AUDIO_IN_INT_IRQ, AUDIO_IN_IRQ_PREPRIO, 0);
00780   HAL_NVIC_EnableIRQ(AUDIO_IN_INT_IRQ);
00781 }
00782 
00783 /**
00784   * @brief  De-Initializes SAI Audio IN MSP.
00785   * @param  hsai: SAI handle
00786   * @param  Params  
00787   * @retval None
00788   */
00789 static void SAI_AUDIO_IN_MspDeInit(SAI_HandleTypeDef *hsai, void *Params)
00790 {
00791   GPIO_InitTypeDef  gpio_init_structure;
00792   
00793   /* SAI DMA IRQ Channel deactivation */
00794   HAL_NVIC_DisableIRQ(AUDIO_IN_SAIx_DMAx_IRQ);
00795   
00796   if(hsai->Instance == AUDIO_IN_SAIx)
00797   {
00798     /* Deinitialize the DMA stream */
00799     HAL_DMA_DeInit(hsai->hdmatx);
00800   }
00801   
00802   /* Disable SAI peripheral */
00803   __HAL_SAI_DISABLE(hsai);  
00804   
00805   /* Deactivates CODEC_SAI pin SD by putting them in input mode */
00806   gpio_init_structure.Pin = AUDIO_IN_SAIx_SD_PIN;
00807   HAL_GPIO_DeInit(AUDIO_IN_SAIx_SD_GPIO_PORT, gpio_init_structure.Pin);
00808   
00809   gpio_init_structure.Pin = AUDIO_IN_INT_GPIO_PIN;
00810   HAL_GPIO_DeInit(AUDIO_IN_INT_GPIO_PORT, gpio_init_structure.Pin);
00811   
00812   /* Disable SAI clock */
00813   AUDIO_IN_SAIx_CLK_DISABLE();  
00814 }
00815 
00816 /**
00817   * @brief  Deinitializes SAI MSP.
00818   * @param  hsai: SAI handle
00819   * @param  Params  
00820   * @retval None
00821   */
00822 __weak void BSP_AUDIO_OUT_MspDeInit(SAI_HandleTypeDef *hsai, void *Params)
00823 {
00824     GPIO_InitTypeDef  gpio_init_structure;
00825 
00826     /* SAI DMA IRQ Channel deactivation */
00827     HAL_NVIC_DisableIRQ(AUDIO_OUT_SAIx_DMAx_IRQ);
00828 
00829     if(hsai->Instance == AUDIO_OUT_SAIx)
00830     {
00831       /* Deinitialize the DMA stream */
00832       HAL_DMA_DeInit(hsai->hdmatx);
00833     }
00834 
00835     /* Disable SAI peripheral */
00836     __HAL_SAI_DISABLE(hsai);  
00837 
00838     /* Deactivates CODEC_SAI pins FS, SCK, MCK and SD by putting them in input mode */
00839     gpio_init_structure.Pin = AUDIO_OUT_SAIx_FS_PIN | AUDIO_OUT_SAIx_SCK_PIN | AUDIO_OUT_SAIx_SD_PIN;
00840     HAL_GPIO_DeInit(AUDIO_OUT_SAIx_SD_FS_SCK_GPIO_PORT, gpio_init_structure.Pin);
00841 
00842     gpio_init_structure.Pin = AUDIO_OUT_SAIx_MCLK_PIN;
00843     HAL_GPIO_DeInit(AUDIO_OUT_SAIx_MCLK_GPIO_PORT, gpio_init_structure.Pin);
00844   
00845     /* Disable SAI clock */
00846     AUDIO_OUT_SAIx_CLK_DISABLE();
00847 
00848     /* GPIO pins clock and DMA clock can be shut down in the applic 
00849        by surcharging this __weak function */ 
00850 }
00851 
00852 /**
00853   * @brief  Clock Config.
00854   * @param  hsai: might be required to set audio peripheral predivider if any.
00855   * @param  AudioFreq: Audio frequency used to play the audio stream.
00856   * @param  Params  
00857   * @note   This API is called by BSP_AUDIO_OUT_Init() and BSP_AUDIO_OUT_SetFrequency()
00858   *         Being __weak it can be overwritten by the application     
00859   * @retval None
00860   */
00861 __weak void BSP_AUDIO_OUT_ClockConfig(SAI_HandleTypeDef *hsai, uint32_t AudioFreq, void *Params)
00862 { 
00863   RCC_PeriphCLKInitTypeDef rcc_ex_clk_init_struct;
00864 
00865   HAL_RCCEx_GetPeriphCLKConfig(&rcc_ex_clk_init_struct);
00866   
00867   /* Set the PLL configuration according to the audio frequency */
00868   if((AudioFreq == AUDIO_FREQUENCY_11K) || (AudioFreq == AUDIO_FREQUENCY_22K) || (AudioFreq == AUDIO_FREQUENCY_44K))
00869   {
00870     /* Configure PLLSAI prescalers */
00871     /* PLLSAI_VCO: VCO_429M 
00872     SAI_CLK(first level) = PLLSAI_VCO/PLLSAIQ = 429/2 = 214.5 Mhz
00873     SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ = 214.5/19 = 11.289 Mhz */ 
00874     rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
00875     rcc_ex_clk_init_struct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLI2S;
00876     rcc_ex_clk_init_struct.PLLI2S.PLLI2SN = 429;
00877     rcc_ex_clk_init_struct.PLLI2S.PLLI2SQ = 2;
00878     rcc_ex_clk_init_struct.PLLI2SDivQ = 19;
00879     
00880     HAL_RCCEx_PeriphCLKConfig(&rcc_ex_clk_init_struct);
00881     
00882   }
00883   else /* AUDIO_FREQUENCY_8K, AUDIO_FREQUENCY_16K, AUDIO_FREQUENCY_48K, AUDIO_FREQUENCY_96K */
00884   {
00885     /* SAI clock config 
00886     PLLSAI_VCO: VCO_344M 
00887     SAI_CLK(first level) = PLLSAI_VCO/PLLSAIQ = 344/7 = 49.142 Mhz 
00888     SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ = 49.142/1 = 49.142 Mhz */  
00889     rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
00890     rcc_ex_clk_init_struct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLI2S;
00891     rcc_ex_clk_init_struct.PLLI2S.PLLI2SN = 344; 
00892     rcc_ex_clk_init_struct.PLLI2S.PLLI2SQ = 7; 
00893     rcc_ex_clk_init_struct.PLLI2SDivQ = 1;      
00894     
00895     HAL_RCCEx_PeriphCLKConfig(&rcc_ex_clk_init_struct);
00896   }
00897 }
00898 
00899 /*******************************************************************************
00900                             Static Functions
00901 *******************************************************************************/
00902 
00903 /**
00904   * @brief  Initializes the Audio Codec audio interface (SAI).
00905   * @param  AudioFreq: Audio frequency to be configured for the SAI peripheral.
00906   * @note   The default SlotActive configuration is set to CODEC_AUDIOFRAME_SLOT_0123 
00907   *         and user can update this configuration using 
00908   * @retval None
00909   */
00910 static void SAIx_Out_Init(uint32_t AudioFreq)
00911 {
00912   /* Initialize the haudio_out_sai Instance parameter */
00913   haudio_out_sai.Instance = AUDIO_OUT_SAIx;
00914   
00915   /* Disable SAI peripheral to allow access to SAI internal registers */
00916   __HAL_SAI_DISABLE(&haudio_out_sai);
00917   
00918   /* Configure SAI_Block_x 
00919   LSBFirst: Disabled 
00920   DataSize: 16 */
00921   haudio_out_sai.Init.MonoStereoMode = SAI_STEREOMODE;
00922   haudio_out_sai.Init.AudioFrequency = AudioFreq;
00923   haudio_out_sai.Init.AudioMode = SAI_MODEMASTER_TX;
00924   haudio_out_sai.Init.NoDivider = SAI_MASTERDIVIDER_ENABLED;
00925   haudio_out_sai.Init.Protocol = SAI_FREE_PROTOCOL;
00926   haudio_out_sai.Init.DataSize = SAI_DATASIZE_16;
00927   haudio_out_sai.Init.FirstBit = SAI_FIRSTBIT_MSB;
00928   haudio_out_sai.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
00929   haudio_out_sai.Init.Synchro = SAI_ASYNCHRONOUS;
00930   haudio_out_sai.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLED;
00931   haudio_out_sai.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
00932   haudio_out_sai.Init.SynchroExt     = SAI_SYNCEXT_DISABLE;
00933   haudio_out_sai.Init.CompandingMode = SAI_NOCOMPANDING;
00934   haudio_out_sai.Init.TriState       = SAI_OUTPUT_NOTRELEASED;
00935   haudio_out_sai.Init.Mckdiv         = 0;
00936     
00937   /* Configure SAI_Block_x Frame 
00938   Frame Length: 64
00939   Frame active Length: 32
00940   FS Definition: Start frame + Channel Side identification
00941   FS Polarity: FS active Low
00942   FS Offset: FS asserted one bit before the first bit of slot 0 */ 
00943   haudio_out_sai.FrameInit.FrameLength = 128; 
00944   haudio_out_sai.FrameInit.ActiveFrameLength = 64;
00945   haudio_out_sai.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
00946   haudio_out_sai.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
00947   haudio_out_sai.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
00948   
00949   /* Configure SAI Block_x Slot 
00950   Slot First Bit Offset: 0
00951   Slot Size  : 16
00952   Slot Number: 4
00953   Slot Active: All slot actives */
00954   haudio_out_sai.SlotInit.FirstBitOffset = 0;
00955   haudio_out_sai.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
00956   haudio_out_sai.SlotInit.SlotNumber = 4; 
00957   haudio_out_sai.SlotInit.SlotActive = CODEC_AUDIOFRAME_SLOT_0123;
00958 
00959   HAL_SAI_Init(&haudio_out_sai);
00960   
00961   /* Enable SAI peripheral to generate MCLK */
00962   __HAL_SAI_ENABLE(&haudio_out_sai);
00963 }
00964 
00965 /**
00966   * @brief  Deinitializes the Audio Codec audio interface (SAI).
00967   * @retval None
00968   */
00969 static void SAIx_Out_DeInit(void)
00970 {
00971   /* Initialize the haudio_out_sai Instance parameter */
00972   haudio_out_sai.Instance = AUDIO_OUT_SAIx;
00973 
00974   /* Disable SAI peripheral */
00975   __HAL_SAI_DISABLE(&haudio_out_sai);
00976 
00977   HAL_SAI_DeInit(&haudio_out_sai);
00978 }
00979 
00980 /**
00981   * @brief  Initializes the Audio Codec audio interface (SAI).
00982   * @param  AudioFreq: Audio frequency to be configured for the SAI peripheral.
00983   * @note   The default SlotActive configuration is set to CODEC_AUDIOFRAME_SLOT_0123 
00984   *         and user can update this configuration using 
00985   * @retval None
00986   */
00987 static void SAIx_In_Init(uint32_t AudioFreq)
00988 {
00989   /* Initialize SAI1 block A in MASTER TX */
00990   /* Initialize the haudio_out_sai Instance parameter */
00991   haudio_out_sai.Instance = AUDIO_OUT_SAIx;
00992 
00993   /* Disable SAI peripheral to allow access to SAI internal registers */
00994   __HAL_SAI_DISABLE(&haudio_out_sai);
00995 
00996   /* Configure SAI_Block_x
00997   LSBFirst: Disabled
00998   DataSize: 16 */
00999   haudio_out_sai.Init.MonoStereoMode = SAI_STEREOMODE;
01000   haudio_out_sai.Init.AudioFrequency = AudioFreq;
01001   haudio_out_sai.Init.AudioMode      = SAI_MODEMASTER_RX;
01002   haudio_out_sai.Init.NoDivider      = SAI_MASTERDIVIDER_ENABLE;
01003   haudio_out_sai.Init.Protocol       = SAI_FREE_PROTOCOL;
01004   haudio_out_sai.Init.DataSize       = SAI_DATASIZE_16;
01005   haudio_out_sai.Init.FirstBit       = SAI_FIRSTBIT_MSB;
01006   haudio_out_sai.Init.ClockStrobing  = SAI_CLOCKSTROBING_FALLINGEDGE;
01007   haudio_out_sai.Init.Synchro        = SAI_ASYNCHRONOUS;
01008   haudio_out_sai.Init.OutputDrive    = SAI_OUTPUTDRIVE_ENABLE;
01009   haudio_out_sai.Init.FIFOThreshold  = SAI_FIFOTHRESHOLD_1QF;
01010   haudio_out_sai.Init.SynchroExt     = SAI_SYNCEXT_DISABLE;
01011   haudio_out_sai.Init.CompandingMode = SAI_NOCOMPANDING;
01012   haudio_out_sai.Init.TriState       = SAI_OUTPUT_NOTRELEASED;
01013   haudio_out_sai.Init.Mckdiv         = 0;  
01014 
01015   /* Configure SAI_Block_x Frame
01016   Frame Length: 64
01017   Frame active Length: 32
01018   FS Definition: Start frame + Channel Side identification
01019   FS Polarity: FS active Low
01020   FS Offset: FS asserted one bit before the first bit of slot 0 */
01021   haudio_out_sai.FrameInit.FrameLength       = 64;
01022   haudio_out_sai.FrameInit.ActiveFrameLength = 32;
01023   haudio_out_sai.FrameInit.FSDefinition      = SAI_FS_CHANNEL_IDENTIFICATION;
01024   haudio_out_sai.FrameInit.FSPolarity        = SAI_FS_ACTIVE_LOW;
01025   haudio_out_sai.FrameInit.FSOffset          = SAI_FS_BEFOREFIRSTBIT;
01026 
01027   /* Configure SAI Block_x Slot
01028   Slot First Bit Offset: 0
01029   Slot Size  : 16
01030   Slot Number: 4
01031   Slot Active: All slot actives */
01032   haudio_out_sai.SlotInit.FirstBitOffset = 0;
01033   haudio_out_sai.SlotInit.SlotSize       = SAI_SLOTSIZE_DATASIZE;
01034   haudio_out_sai.SlotInit.SlotNumber     = 4;
01035   haudio_out_sai.SlotInit.SlotActive     = CODEC_AUDIOFRAME_SLOT_02;
01036 
01037   HAL_SAI_Init(&haudio_out_sai);
01038 
01039   /* Initialize SAI1 block B in SLAVE RX synchronous from SAI1 block A */
01040   /* Initialize the haudio_in_sai Instance parameter */
01041   haudio_in_sai.Instance = AUDIO_IN_SAIx;
01042   
01043   /* Disable SAI peripheral to allow access to SAI internal registers */
01044   __HAL_SAI_DISABLE(&haudio_in_sai);
01045   
01046   /* Configure SAI_Block_x
01047   LSBFirst: Disabled
01048   DataSize: 16 */
01049   haudio_in_sai.Init.MonoStereoMode = SAI_STEREOMODE;
01050   haudio_in_sai.Init.AudioFrequency = AudioFreq;
01051   haudio_in_sai.Init.AudioMode      = SAI_MODESLAVE_RX;
01052   haudio_in_sai.Init.NoDivider      = SAI_MASTERDIVIDER_ENABLE;
01053   haudio_in_sai.Init.Protocol       = SAI_FREE_PROTOCOL;
01054   haudio_in_sai.Init.DataSize       = SAI_DATASIZE_16;
01055   haudio_in_sai.Init.FirstBit       = SAI_FIRSTBIT_MSB;
01056   haudio_in_sai.Init.ClockStrobing  = SAI_CLOCKSTROBING_RISINGEDGE;
01057   haudio_in_sai.Init.Synchro        = SAI_SYNCHRONOUS;
01058   haudio_in_sai.Init.OutputDrive    = SAI_OUTPUTDRIVE_DISABLE;
01059   haudio_in_sai.Init.FIFOThreshold  = SAI_FIFOTHRESHOLD_1QF;
01060   haudio_in_sai.Init.SynchroExt     = SAI_SYNCEXT_DISABLE;
01061   haudio_in_sai.Init.CompandingMode = SAI_NOCOMPANDING;
01062   haudio_in_sai.Init.TriState       = SAI_OUTPUT_RELEASED;
01063   haudio_in_sai.Init.Mckdiv         = 0;
01064 
01065   /* Configure SAI_Block_x Frame
01066   Frame Length: 64
01067   Frame active Length: 32
01068   FS Definition: Start frame + Channel Side identification
01069   FS Polarity: FS active Low
01070   FS Offset: FS asserted one bit before the first bit of slot 0 */
01071   haudio_in_sai.FrameInit.FrameLength       = 64;
01072   haudio_in_sai.FrameInit.ActiveFrameLength = 32;
01073   haudio_in_sai.FrameInit.FSDefinition      = SAI_FS_CHANNEL_IDENTIFICATION;
01074   haudio_in_sai.FrameInit.FSPolarity        = SAI_FS_ACTIVE_LOW;
01075   haudio_in_sai.FrameInit.FSOffset          = SAI_FS_BEFOREFIRSTBIT;
01076   
01077   /* Configure SAI Block_x Slot
01078   Slot First Bit Offset: 0
01079   Slot Size  : 16
01080   Slot Number: 4
01081   Slot Active: All slot active */
01082   haudio_in_sai.SlotInit.FirstBitOffset = 0;
01083   haudio_in_sai.SlotInit.SlotSize       = SAI_SLOTSIZE_DATASIZE;
01084   haudio_in_sai.SlotInit.SlotNumber     = 4;
01085   haudio_in_sai.SlotInit.SlotActive     = CODEC_AUDIOFRAME_SLOT_02;
01086 
01087   HAL_SAI_Init(&haudio_in_sai);
01088 
01089   /* Enable SAI peripheral */
01090   __HAL_SAI_ENABLE(&haudio_in_sai);
01091 
01092   /* Enable SAI peripheral to generate MCLK */
01093   __HAL_SAI_ENABLE(&haudio_out_sai);
01094 }
01095 
01096 /**
01097   * @brief  Deinitializes the output Audio Codec audio interface (SAI).
01098   * @retval None
01099   */
01100 static void SAIx_In_DeInit(void)
01101 {
01102   /* Initialize the haudio_in_sai Instance parameter */
01103   haudio_in_sai.Instance = AUDIO_IN_SAIx;
01104   haudio_out_sai.Instance = AUDIO_OUT_SAIx;
01105   /* Disable SAI peripheral */
01106   __HAL_SAI_DISABLE(&haudio_in_sai);
01107 
01108   HAL_SAI_DeInit(&haudio_in_sai);
01109   HAL_SAI_DeInit(&haudio_out_sai);
01110 }
01111 
01112 /**
01113   * @}
01114   */
01115 
01116 /** @defgroup STM32F769I_DISCOVERY_AUDIO_In_Private_Functions STM32F769I_DISCOVERY_AUDIO_In Private Functions
01117   * @{
01118   */
01119 
01120 /**
01121   * @brief  Initialize wave recording. 
01122   * @param  AudioFreq: Audio frequency to be configured for the DFSDM peripheral. 
01123   * @param  BitRes: Audio frequency to be configured for the DFSDM peripheral.
01124   * @param  ChnlNbr: Audio frequency to be configured for the DFSDM peripheral.
01125   * @retval AUDIO_OK if correct communication, else wrong communication
01126   */
01127 uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
01128 { 
01129   return BSP_AUDIO_IN_InitEx(INPUT_DEVICE_DIGITAL_MIC, AudioFreq, BitRes, ChnlNbr);
01130 }
01131 
01132 /**
01133   * @brief  Initialize wave recording.
01134   * @param  InputDevice: INPUT_DEVICE_DIGITAL_MIC or INPUT_DEVICE_ANALOG_MIC. 
01135   * @param  AudioFreq: Audio frequency to be configured. 
01136   * @param  BitRes: Audio bit resolution to be configured..
01137   * @param  ChnlNbr: Number of channel to be configured.
01138   * @retval AUDIO_OK if correct communication, else wrong communication
01139   */
01140 uint8_t BSP_AUDIO_IN_InitEx(uint16_t InputDevice, uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
01141 { 
01142   uint8_t ret = AUDIO_ERROR;
01143   AudioIn_Device = InputDevice;
01144   
01145   if(InputDevice == INPUT_DEVICE_DIGITAL_MIC)
01146   {
01147     AudioIn_ChannelNumber = ChnlNbr;
01148     /* PLL clock is set depending by the AudioFreq (44.1khz vs 48khz groups) */ 
01149     BSP_AUDIO_IN_ClockConfig(&hAudioInTopLeftFilter, AudioFreq, NULL);
01150     
01151     /* Init the SAI MSP: this __weak function can be redefined by the application*/
01152     BSP_AUDIO_IN_MspInit();
01153     
01154     /* Initializes DFSDM peripheral */
01155     DFSDMx_Init(AudioFreq);
01156     ret = AUDIO_OK;
01157   }
01158   else
01159   {
01160     /* Disable SAI */
01161     SAIx_In_DeInit();
01162     
01163     /* PLL clock is set depending by the AudioFreq (44.1khz vs 48khz groups) */ 
01164     BSP_AUDIO_OUT_ClockConfig(&haudio_in_sai, AudioFreq, NULL);
01165     
01166     haudio_in_sai.Instance = AUDIO_IN_SAIx;
01167     if(HAL_SAI_GetState(&haudio_in_sai) == HAL_SAI_STATE_RESET)
01168     {    
01169     BSP_AUDIO_OUT_MspInit(&haudio_in_sai, NULL);
01170     BSP_AUDIO_IN_MspInit();
01171     }
01172 
01173     SAIx_In_Init(AudioFreq);
01174     
01175     if((wm8994_drv.ReadID(AUDIO_I2C_ADDRESS)) == WM8994_ID)
01176     {
01177       /* Reset the Codec Registers */
01178       wm8994_drv.Reset(AUDIO_I2C_ADDRESS);
01179       /* Initialize the audio driver structure */
01180       audio_drv = &wm8994_drv;
01181       ret = AUDIO_OK;
01182     }
01183     else
01184     {
01185       ret = AUDIO_ERROR;
01186     }
01187     
01188     if(ret == AUDIO_OK)
01189     {
01190       /* Initialize the codec internal registers */
01191       audio_drv->Init(AUDIO_I2C_ADDRESS, InputDevice, 100, AudioFreq);
01192     }    
01193   }
01194   
01195   /* Return AUDIO_OK when all operations are correctly done */
01196   return ret;
01197 }
01198 
01199 /**
01200   * @brief  Allocate channel buffer scratch 
01201   * @param  pScratch : pointer to scratch tables.
01202   * @param  size of scratch buffer
01203   */
01204 uint8_t BSP_AUDIO_IN_AllocScratch (int32_t *pScratch, uint32_t size)
01205 { 
01206   uint32_t idx;
01207   
01208   ScratchSize = (size / AudioIn_ChannelNumber);
01209   
01210   /* copy scratch pointers */
01211   for (idx = 0; idx < AudioIn_ChannelNumber; idx++)
01212   {
01213     pScratchBuff[idx] = (int32_t *)(pScratch + (idx * ScratchSize));
01214   }
01215   /* Return AUDIO_OK */
01216   return AUDIO_OK;
01217 }
01218 
01219 /**
01220   * @brief  Return audio in channel number 
01221   * @retval Number of channel
01222   */
01223 uint8_t BSP_AUDIO_IN_GetChannelNumber(void)
01224 {
01225   return AudioIn_ChannelNumber;
01226 }
01227 
01228 /**
01229   * @brief  Start audio recording.
01230   * @param  pbuf: Main buffer pointer for the recorded data storing  
01231   * @param  size: Current size of the recorded buffer
01232   * @retval AUDIO_OK if correct communication, else wrong communication
01233   */
01234 uint8_t BSP_AUDIO_IN_Record(uint16_t* pbuf, uint32_t size)
01235 {  
01236   if (AudioIn_Device == INPUT_DEVICE_DIGITAL_MIC)
01237   {
01238     hAudioIn.pRecBuf = pbuf;
01239     hAudioIn.RecSize = size;
01240     /* Reset Application Buffer Trigger */
01241     AppBuffTrigger = 0;
01242     AppBuffHalf = 0;
01243     
01244     if(AudioIn_ChannelNumber > 2)
01245     {
01246       /* Call the Media layer start function for buttom right channel */
01247       if(HAL_OK != HAL_DFSDM_FilterRegularStart_DMA(&hAudioInButtomRightFilter, pScratchBuff[2], ScratchSize))
01248       {
01249         return AUDIO_ERROR;
01250       } 
01251       
01252       /* Call the Media layer start function for buttom left channel */
01253       if(HAL_OK != HAL_DFSDM_FilterRegularStart_DMA(&hAudioInButtomLeftFilter, pScratchBuff[3], ScratchSize))
01254       {
01255         return AUDIO_ERROR;
01256       }
01257     }
01258 
01259     /* Call the Media layer start function for top right channel */
01260     if(HAL_OK != HAL_DFSDM_FilterRegularStart_DMA(&hAudioInTopRightFilter, pScratchBuff[0], ScratchSize))
01261     {
01262       return AUDIO_ERROR;
01263     }
01264     
01265     /* Call the Media layer start function for top left channel */
01266     if(HAL_OK != HAL_DFSDM_FilterRegularStart_DMA(&hAudioInTopLeftFilter, pScratchBuff[1], ScratchSize))
01267     {
01268       return AUDIO_ERROR;
01269     }
01270   }
01271   else
01272   {
01273     /* Start the process receive DMA */
01274     if(HAL_OK !=HAL_SAI_Receive_DMA(&haudio_in_sai, (uint8_t*)pbuf, size))
01275     {
01276       return AUDIO_ERROR;
01277     }
01278   }
01279   /* Return AUDIO_OK when all operations are correctly done */
01280   return AUDIO_OK;  
01281 }
01282 
01283 /**
01284   * @brief  Stop audio recording.
01285   * @retval AUDIO_OK if correct communication, else wrong communication
01286   */
01287 uint8_t BSP_AUDIO_IN_Stop(void)
01288 {
01289   if (AudioIn_Device == INPUT_DEVICE_DIGITAL_MIC)
01290   { 
01291     AppBuffTrigger = 0;
01292     AppBuffHalf    = 0;
01293     
01294     if(AudioIn_ChannelNumber > 2)
01295     {    
01296       /* Call the Media layer stop function for buttom right channel */
01297       if(HAL_OK != HAL_DFSDM_FilterRegularStop_DMA(&hAudioInButtomRightFilter))
01298       {
01299         return AUDIO_ERROR;
01300       }
01301       
01302       /* Call the Media layer stop function for buttom left channel */
01303       if(HAL_OK != HAL_DFSDM_FilterRegularStop_DMA(&hAudioInButtomLeftFilter))
01304       {
01305         return AUDIO_ERROR;
01306       }
01307     }
01308     
01309     /* Call the Media layer stop function for top right channel */
01310     if(HAL_OK != HAL_DFSDM_FilterRegularStop_DMA(&hAudioInTopRightFilter))
01311     {
01312       return AUDIO_ERROR;
01313     }
01314     
01315     /* Call the Media layer stop function for top left channel */
01316     if(HAL_OK != HAL_DFSDM_FilterRegularStop_DMA(&hAudioInTopLeftFilter))
01317     {
01318       return AUDIO_ERROR;
01319     }
01320   }
01321   else
01322   {
01323     /* Call the Media layer stop function */
01324     HAL_SAI_DMAStop(&haudio_in_sai);
01325     
01326     /* Call Audio Codec Stop function */
01327     if(audio_drv->Stop(AUDIO_I2C_ADDRESS, CODEC_PDWN_HW) != 0)
01328     {
01329       return AUDIO_ERROR;
01330     }
01331     else
01332     {
01333       /* Wait at least 100us */
01334       HAL_Delay(1);
01335       
01336       /* Return AUDIO_OK when all operations are correctly done */
01337       return AUDIO_OK;
01338     }  
01339   }
01340   /* Return AUDIO_OK when all operations are correctly done */
01341   return AUDIO_OK;
01342 }
01343 
01344 /**
01345   * @brief  Pause the audio file stream.
01346   * @retval AUDIO_OK if correct communication, else wrong communication
01347   */
01348 uint8_t BSP_AUDIO_IN_Pause(void)
01349 {
01350   if(AudioIn_ChannelNumber > 2)
01351   { 
01352     /* Call the Media layer stop function */
01353     if(HAL_OK != HAL_DFSDM_FilterRegularStop_DMA(&hAudioInButtomRightFilter))
01354     {
01355       return AUDIO_ERROR;
01356     }
01357     
01358     /* Call the Media layer stop function */
01359     if(HAL_OK != HAL_DFSDM_FilterRegularStop_DMA(&hAudioInButtomLeftFilter))
01360     {
01361       return AUDIO_ERROR;
01362     }
01363   }  
01364   /* Call the Media layer stop function */
01365   if(HAL_OK != HAL_DFSDM_FilterRegularStop_DMA(&hAudioInTopRightFilter))
01366   {
01367     return AUDIO_ERROR;
01368   }
01369   
01370   /* Call the Media layer stop function */
01371   if(HAL_OK != HAL_DFSDM_FilterRegularStop_DMA(&hAudioInTopLeftFilter))
01372   {
01373     return AUDIO_ERROR;
01374   }
01375   
01376   /* Return AUDIO_OK when all operations are correctly done */
01377   return AUDIO_OK;
01378 }
01379 
01380 /**
01381   * @brief  Resume the audio file stream.
01382   * @retval AUDIO_OK if correct communication, else wrong communication
01383   */
01384 uint8_t BSP_AUDIO_IN_Resume(void)
01385 { 
01386   if(AudioIn_ChannelNumber > 2)
01387   {   
01388     /* Call the Media layer start function for buttom right channel */
01389     if(HAL_OK != HAL_DFSDM_FilterRegularStart_DMA(&hAudioInButtomRightFilter, pScratchBuff[2], ScratchSize))
01390     {
01391       return AUDIO_ERROR;
01392     }
01393     
01394     /* Call the Media layer start function for buttom left channel */
01395     if(HAL_OK != HAL_DFSDM_FilterRegularStart_DMA(&hAudioInButtomLeftFilter, pScratchBuff[3], ScratchSize))
01396     {
01397       return AUDIO_ERROR;
01398     }
01399   } 
01400   /* Call the Media layer start function for top right channel */
01401   if(HAL_OK != HAL_DFSDM_FilterRegularStart_DMA(&hAudioInTopRightFilter, pScratchBuff[0], ScratchSize))
01402   {
01403     return AUDIO_ERROR;
01404   }
01405   
01406   /* Call the Media layer start function for top left channel */
01407   if(HAL_OK != HAL_DFSDM_FilterRegularStart_DMA(&hAudioInTopLeftFilter, pScratchBuff[1], ScratchSize))
01408   {
01409     return AUDIO_ERROR;
01410   }
01411   
01412   /* Return AUDIO_OK when all operations are correctly done */
01413   return AUDIO_OK;
01414 }
01415 
01416 /**
01417   * @brief  Deinit the audio IN peripherals.
01418   * @retval None
01419   */
01420 void BSP_AUDIO_IN_DeInit(void)
01421 {
01422   BSP_AUDIO_IN_MspDeInit();
01423   
01424   if(AudioIn_Device == INPUT_DEVICE_DIGITAL_MIC)
01425   {
01426     DFSDMx_DeInit();
01427   }
01428   else
01429   {
01430     SAIx_In_DeInit();
01431   }
01432 }
01433 
01434 /**
01435   * @brief  Regular conversion complete callback. 
01436   * @note   In interrupt mode, user has to read conversion value in this function
01437             using HAL_DFSDM_FilterGetRegularValue.
01438   * @param  hdfsdm_filter : DFSDM filter handle.
01439   * @retval None
01440   */
01441 void HAL_DFSDM_FilterRegConvCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
01442 {
01443   int32_t index = 0;
01444   
01445   if(hdfsdm_filter == &hAudioInTopLeftFilter)
01446   {
01447     DmaTopLeftRecCplt = 1;
01448   }
01449   else if(hdfsdm_filter == &hAudioInTopRightFilter)
01450   {
01451     DmaTopRightRecCplt = 1;
01452   }
01453   else if(hdfsdm_filter == &hAudioInButtomLeftFilter)
01454   {
01455     DmaButtomLeftRecCplt = 1;
01456   }
01457   else
01458   {
01459     DmaButtomRightRecCplt = 1;
01460   }
01461   
01462   if(AudioIn_ChannelNumber > 2)
01463   {
01464     if((DmaTopLeftRecCplt == 1) && (DmaTopRightRecCplt == 1) && (DmaButtomLeftRecCplt == 1) && (DmaButtomRightRecCplt == 1))
01465     {
01466       for(index = (ScratchSize/2) ; index < ScratchSize; index++)
01467       {
01468         hAudioIn.pRecBuf[AppBuffTrigger]     = (uint16_t)(SaturaLH((pScratchBuff[1][index] >> 8), -32760, 32760));
01469         hAudioIn.pRecBuf[AppBuffTrigger + 1] = (uint16_t)(SaturaLH((pScratchBuff[0][index] >> 8), -32760, 32760));       
01470         hAudioIn.pRecBuf[AppBuffTrigger + 2] = (uint16_t)(SaturaLH((pScratchBuff[3][index] >> 8), -32760, 32760));
01471         hAudioIn.pRecBuf[AppBuffTrigger + 3] = (uint16_t)(SaturaLH((pScratchBuff[2][index] >> 8), -32760, 32760));      
01472         AppBuffTrigger +=4;
01473       }
01474       DmaTopLeftRecCplt  = 0;
01475       DmaTopRightRecCplt = 0;
01476       DmaButtomLeftRecCplt  = 0;
01477       DmaButtomRightRecCplt = 0;     
01478     }
01479   }
01480   else
01481   {
01482     if((DmaTopLeftRecCplt == 1) && (DmaTopRightRecCplt == 1))
01483     {    
01484       for(index = (ScratchSize/2) ; index < ScratchSize; index++)
01485       {
01486         hAudioIn.pRecBuf[AppBuffTrigger]     = (uint16_t)(SaturaLH((pScratchBuff[1][index] >> 8), -32760, 32760));
01487         hAudioIn.pRecBuf[AppBuffTrigger + 1] = (uint16_t)(SaturaLH((pScratchBuff[0][index] >> 8), -32760, 32760));
01488         AppBuffTrigger +=2;
01489       }
01490       DmaTopLeftRecCplt  = 0;
01491       DmaTopRightRecCplt = 0;  
01492     }
01493   }
01494   
01495   /* Call Half Transfer Complete callback */
01496   if((AppBuffTrigger == hAudioIn.RecSize/2) && (AppBuffHalf == 0))
01497   {
01498     AppBuffHalf = 1;  
01499     BSP_AUDIO_IN_HalfTransfer_CallBack();
01500   }
01501   /* Call Transfer Complete callback */
01502   if(AppBuffTrigger == hAudioIn.RecSize)
01503   {
01504     /* Reset Application Buffer Trigger */
01505     AppBuffTrigger = 0;
01506     AppBuffHalf = 0; 
01507     /* Call the record update function to get the next buffer to fill and its size (size is ignored) */
01508     BSP_AUDIO_IN_TransferComplete_CallBack();
01509   }  
01510 }
01511 
01512 /**
01513   * @brief  Half regular conversion complete callback. 
01514   * @param  hdfsdm_filter : DFSDM filter handle.
01515   * @retval None
01516   */
01517 void HAL_DFSDM_FilterRegConvHalfCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
01518 {
01519   int32_t index = 0;
01520   
01521   if(hdfsdm_filter == &hAudioInTopLeftFilter)
01522   {
01523     DmaTopLeftRecHalfCplt = 1;
01524   }
01525   else if(hdfsdm_filter == &hAudioInTopRightFilter)
01526   {
01527     DmaTopRightRecHalfCplt = 1;
01528   }
01529   else if(hdfsdm_filter == &hAudioInButtomLeftFilter)
01530   {
01531     DmaButtomLeftRecHalfCplt = 1;
01532   }
01533   else
01534   {
01535     DmaButtomRightRecHalfCplt = 1;
01536   }
01537   
01538   if(AudioIn_ChannelNumber > 2)
01539   {
01540     if((DmaTopLeftRecHalfCplt == 1) && (DmaTopRightRecHalfCplt == 1) && (DmaButtomLeftRecHalfCplt == 1) && (DmaButtomRightRecHalfCplt == 1))
01541     {
01542       for(index = 0 ; index < ScratchSize/2; index++)
01543       {
01544         hAudioIn.pRecBuf[AppBuffTrigger]     = (uint16_t)(SaturaLH((pScratchBuff[1][index] >> 8), -32760, 32760));
01545         hAudioIn.pRecBuf[AppBuffTrigger + 1] = (uint16_t)(SaturaLH((pScratchBuff[0][index] >> 8), -32760, 32760)); 
01546         hAudioIn.pRecBuf[AppBuffTrigger + 2] = (uint16_t)(SaturaLH((pScratchBuff[3][index] >> 8), -32760, 32760));
01547         hAudioIn.pRecBuf[AppBuffTrigger + 3] = (uint16_t)(SaturaLH((pScratchBuff[2][index] >> 8), -32760, 32760));      
01548         AppBuffTrigger +=4;
01549       }
01550       DmaTopLeftRecHalfCplt  = 0;
01551       DmaTopRightRecHalfCplt = 0;
01552       DmaButtomLeftRecHalfCplt  = 0;
01553       DmaButtomRightRecHalfCplt = 0;     
01554     }
01555   }
01556   else
01557   {
01558     if((DmaTopLeftRecHalfCplt == 1) && (DmaTopRightRecHalfCplt == 1))
01559     {    
01560       for(index = 0 ; index < ScratchSize/2; index++)
01561       {
01562         hAudioIn.pRecBuf[AppBuffTrigger]     = (uint16_t)(SaturaLH((pScratchBuff[1][index] >> 8), -32760, 32760));
01563         hAudioIn.pRecBuf[AppBuffTrigger + 1] = (uint16_t)(SaturaLH((pScratchBuff[0][index] >> 8), -32760, 32760));
01564         AppBuffTrigger +=2;
01565       }
01566       DmaTopLeftRecHalfCplt  = 0;
01567       DmaTopRightRecHalfCplt = 0;  
01568     }
01569   }
01570   
01571   /* Call Half Transfer Complete callback */
01572   if((AppBuffTrigger == hAudioIn.RecSize/2) && (AppBuffHalf == 0))
01573   { 
01574     AppBuffHalf = 1;  
01575     BSP_AUDIO_IN_HalfTransfer_CallBack();
01576   }
01577   /* Call Transfer Complete callback */
01578   if(AppBuffTrigger == hAudioIn.RecSize)
01579   {
01580     /* Reset Application Buffer Trigger */
01581     AppBuffTrigger = 0;
01582     AppBuffHalf = 0;
01583     /* Call the record update function to get the next buffer to fill and its size (size is ignored) */
01584     BSP_AUDIO_IN_TransferComplete_CallBack();
01585   }  
01586 }
01587 
01588 /**
01589   * @brief  Half reception complete callback.
01590   * @param  hsai : SAI handle.
01591   * @retval None
01592   */
01593 void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai)
01594 {
01595   /* Manage the remaining file size and new address offset: This function 
01596      should be coded by user (its prototype is already declared in stm32769i_discovery_audio.h) */
01597   BSP_AUDIO_IN_HalfTransfer_CallBack();
01598 }
01599 
01600 /**
01601   * @brief  Reception complete callback.
01602   * @param  hsai : SAI handle.
01603   * @retval None
01604   */
01605 void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai)
01606 {
01607   /* Call the record update function to get the next buffer to fill and its size (size is ignored) */
01608   BSP_AUDIO_IN_TransferComplete_CallBack();
01609 }
01610 
01611 /**
01612   * @brief  User callback when record buffer is filled.
01613   * @retval None
01614   */
01615 __weak void BSP_AUDIO_IN_TransferComplete_CallBack(void)
01616 {
01617   /* This function should be implemented by the user application.
01618      It is called into this driver when the current buffer is filled
01619      to prepare the next buffer pointer and its size. */
01620 }
01621 
01622 /**
01623   * @brief  Manages the DMA Half Transfer complete event.
01624   * @retval None
01625   */
01626 __weak void BSP_AUDIO_IN_HalfTransfer_CallBack(void)
01627 { 
01628   /* This function should be implemented by the user application.
01629      It is called into this driver when the current buffer is filled
01630      to prepare the next buffer pointer and its size. */
01631 }
01632 
01633 /**
01634   * @brief  Audio IN Error callback function.
01635   * @retval None
01636   */
01637 __weak void BSP_AUDIO_IN_Error_CallBack(void)
01638 {   
01639   /* This function is called when an Interrupt due to transfer error on or peripheral
01640      error occurs. */
01641 }
01642 
01643 /**
01644   * @brief  Initialize BSP_AUDIO_IN MSP.
01645   * @retval None
01646   */
01647 __weak void BSP_AUDIO_IN_MspInit(void)
01648 { 
01649   if (AudioIn_Device == INPUT_DEVICE_DIGITAL_MIC)
01650   {  
01651   /* MSP channels initialization */
01652   DFSDMx_ChannelMspInit();  
01653   /* MSP filters initialization */
01654   DFSDMx_FilterMspInit();
01655   }
01656   else
01657   {
01658    SAI_AUDIO_IN_MspInit(&haudio_in_sai, NULL); 
01659   }
01660 }
01661 
01662 /**
01663   * @brief  DeInitialize BSP_AUDIO_IN MSP.
01664   * @retval None
01665   */
01666 __weak void BSP_AUDIO_IN_MspDeInit(void)
01667 {
01668   if (AudioIn_Device == INPUT_DEVICE_DIGITAL_MIC)
01669   {  
01670     /* MSP channels initialization */
01671     DFSDMx_ChannelMspDeInit();  
01672     /* MSP filters initialization */
01673     DFSDMx_FilterMspDeInit();
01674   }
01675   else
01676   {
01677     SAI_AUDIO_IN_MspDeInit(&haudio_in_sai, NULL); 
01678   }
01679 }
01680 
01681 /**
01682   * @brief  Clock Config.
01683   * @param  hdfsdm_filter: might be required to set audio peripheral predivider if any.
01684   * @param  AudioFreq: Audio frequency used to play the audio stream.
01685   * @param  Params  
01686   * @note   This API is called by BSP_AUDIO_IN_Init()
01687   *         Being __weak it can be overwritten by the application     
01688   * @retval None
01689   */
01690 __weak void BSP_AUDIO_IN_ClockConfig(DFSDM_Filter_HandleTypeDef *hdfsdm_filter, uint32_t AudioFreq, void *Params)
01691 { 
01692   RCC_PeriphCLKInitTypeDef rcc_ex_clk_init_struct;
01693 
01694   HAL_RCCEx_GetPeriphCLKConfig(&rcc_ex_clk_init_struct);
01695   
01696   /* Set the PLL configuration according to the audio frequency */
01697   if((AudioFreq == AUDIO_FREQUENCY_11K) || (AudioFreq == AUDIO_FREQUENCY_22K) || (AudioFreq == AUDIO_FREQUENCY_44K))
01698   {
01699     /* Configure PLLSAI prescalers */
01700     /* PLLI2S_VCO: VCO_429M 
01701     SAI_CLK(first level) = PLLI2S_VCO/PLLI2SQ = 429/2 = 214.5 Mhz
01702     SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ = 214.5/19 = 11.289 Mhz */ 
01703     rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI2;
01704     rcc_ex_clk_init_struct.Sai2ClockSelection = RCC_SAI2CLKSOURCE_PLLI2S;
01705     rcc_ex_clk_init_struct.PLLI2S.PLLI2SN = 429;
01706     rcc_ex_clk_init_struct.PLLI2S.PLLI2SQ = 2;
01707     rcc_ex_clk_init_struct.PLLI2SDivQ = 19;
01708     
01709     HAL_RCCEx_PeriphCLKConfig(&rcc_ex_clk_init_struct);
01710     
01711   }
01712   else /* AUDIO_FREQUENCY_8K, AUDIO_FREQUENCY_16K, AUDIO_FREQUENCY_32K, AUDIO_FREQUENCY_48K, AUDIO_FREQUENCY_96K */
01713   {
01714     /* SAI clock config 
01715     PLLI2S_VCO: VCO_344M 
01716     SAI_CLK(first level) = PLLI2S_VCO/PLLI2SQ = 344/7 = 49.142 Mhz 
01717     SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ = 49.142/1 = 49.142 Mhz */  
01718     rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI2;
01719     rcc_ex_clk_init_struct.Sai2ClockSelection = RCC_SAI2CLKSOURCE_PLLI2S;
01720     rcc_ex_clk_init_struct.PLLI2S.PLLI2SN = 344; 
01721     rcc_ex_clk_init_struct.PLLI2S.PLLI2SQ = 7; 
01722     rcc_ex_clk_init_struct.PLLI2SDivQ = 1;   
01723     HAL_RCCEx_PeriphCLKConfig(&rcc_ex_clk_init_struct);
01724   }
01725   
01726   rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_DFSDM1_AUDIO;
01727   rcc_ex_clk_init_struct.Dfsdm1AudioClockSelection = RCC_DFSDM1AUDIOCLKSOURCE_SAI2;
01728   HAL_RCCEx_PeriphCLKConfig(&rcc_ex_clk_init_struct); 
01729 }
01730 
01731 /*******************************************************************************
01732                             Static Functions
01733 *******************************************************************************/
01734 /**
01735   * @brief  Initialize the Digital Filter for Sigma-Delta Modulators interface (DFSDM).
01736   * @param  AudioFreq: Audio frequency to be used to set correctly the DFSDM peripheral.
01737   * @note   Channel output Clock Divider and Filter Oversampling are calculated as follow: 
01738   *         - Clock_Divider = CLK(input DFSDM)/CLK(micro) with
01739   *           1MHZ < CLK(micro) < 3.2MHZ (TYP 2.4MHZ for MP34DT01TR)
01740   *         - Oversampling = CLK(input DFSDM)/(Clock_Divider * AudioFreq)  
01741   * @retval AUDIO_OK if correct communication, else wrong communication
01742   */
01743 static uint8_t DFSDMx_Init(uint32_t AudioFreq)
01744 {
01745   /****************************************************************************/ 
01746   /********************** Channels configuration  *****************************/
01747   /****************************************************************************/ 
01748   /* CHANNEL 1 configuration */
01749   __HAL_DFSDM_CHANNEL_RESET_HANDLE_STATE(&hAudioInTopLeftChannel);  
01750   hAudioInTopLeftChannel.Instance                      = DFSDM1_Channel1;  
01751   hAudioInTopLeftChannel.Init.OutputClock.Activation   = ENABLE;
01752   hAudioInTopLeftChannel.Init.OutputClock.Selection    = DFSDM_CHANNEL_OUTPUT_CLOCK_AUDIO;
01753   /* Set the DFSDM clock OUT audio frequency configuration */
01754   hAudioInTopLeftChannel.Init.OutputClock.Divider      = DFSDM_CLOCK_DIVIDER(AudioFreq);
01755   hAudioInTopLeftChannel.Init.Input.Multiplexer        = DFSDM_CHANNEL_EXTERNAL_INPUTS;
01756   hAudioInTopLeftChannel.Init.Input.DataPacking        = DFSDM_CHANNEL_STANDARD_MODE;
01757   hAudioInTopLeftChannel.Init.Input.Pins               = DFSDM_CHANNEL_SAME_CHANNEL_PINS;
01758   /* Request to sample stable data for LEFT micro on Rising edge */
01759   hAudioInTopLeftChannel.Init.SerialInterface.Type     = DFSDM_CHANNEL_SPI_RISING;
01760   hAudioInTopLeftChannel.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
01761   hAudioInTopLeftChannel.Init.Awd.FilterOrder          = DFSDM_CHANNEL_FASTSINC_ORDER;
01762   hAudioInTopLeftChannel.Init.Awd.Oversampling         = 10;
01763   hAudioInTopLeftChannel.Init.Offset                   = 0;
01764   hAudioInTopLeftChannel.Init.RightBitShift            = DFSDM_RIGHT_BIT_SHIFT(AudioFreq);
01765   if(HAL_OK != HAL_DFSDM_ChannelInit(&hAudioInTopLeftChannel))
01766   {
01767     return AUDIO_ERROR;
01768   }
01769   
01770   /* CHANNEL 0 configuration */
01771   __HAL_DFSDM_CHANNEL_RESET_HANDLE_STATE(&hAudioInTopRightChannel);  
01772   hAudioInTopRightChannel.Instance                      = DFSDM1_Channel0;  
01773   hAudioInTopRightChannel.Init.OutputClock.Activation   = ENABLE;
01774   hAudioInTopRightChannel.Init.OutputClock.Selection    = DFSDM_CHANNEL_OUTPUT_CLOCK_AUDIO;
01775   /* Set the DFSDM clock OUT audio frequency configuration */
01776   hAudioInTopRightChannel.Init.OutputClock.Divider      = DFSDM_CLOCK_DIVIDER(AudioFreq);
01777   hAudioInTopRightChannel.Init.Input.Multiplexer        = DFSDM_CHANNEL_EXTERNAL_INPUTS;
01778   hAudioInTopRightChannel.Init.Input.DataPacking        = DFSDM_CHANNEL_STANDARD_MODE;
01779   hAudioInTopRightChannel.Init.Input.Pins               = DFSDM_CHANNEL_FOLLOWING_CHANNEL_PINS;
01780   /* Request to sample stable data for RIGHT micro on Falling edge */
01781   hAudioInTopRightChannel.Init.SerialInterface.Type     = DFSDM_CHANNEL_SPI_FALLING;
01782   hAudioInTopRightChannel.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
01783   hAudioInTopRightChannel.Init.Awd.FilterOrder          = DFSDM_CHANNEL_FASTSINC_ORDER;
01784   hAudioInTopRightChannel.Init.Awd.Oversampling         = 10;
01785   hAudioInTopRightChannel.Init.Offset                   = 0;
01786   hAudioInTopRightChannel.Init.RightBitShift            = DFSDM_RIGHT_BIT_SHIFT(AudioFreq);
01787   if(HAL_OK != HAL_DFSDM_ChannelInit(&hAudioInTopRightChannel))
01788   {
01789     return AUDIO_ERROR;
01790   }
01791   
01792   if(AudioIn_ChannelNumber > 2)
01793   {  
01794     /* CHANNEL 5 configuration */
01795     __HAL_DFSDM_CHANNEL_RESET_HANDLE_STATE(&hAudioInButtomLeftChannel);  
01796     hAudioInButtomLeftChannel.Instance                      = DFSDM1_Channel5;  
01797     hAudioInButtomLeftChannel.Init.OutputClock.Activation   = ENABLE;
01798     hAudioInButtomLeftChannel.Init.OutputClock.Selection    = DFSDM_CHANNEL_OUTPUT_CLOCK_AUDIO;
01799     /* Set the DFSDM clock OUT audio frequency configuration */
01800     hAudioInButtomLeftChannel.Init.OutputClock.Divider      = DFSDM_CLOCK_DIVIDER(AudioFreq);
01801     hAudioInButtomLeftChannel.Init.Input.Multiplexer        = DFSDM_CHANNEL_EXTERNAL_INPUTS;
01802     hAudioInButtomLeftChannel.Init.Input.DataPacking        = DFSDM_CHANNEL_STANDARD_MODE;
01803     hAudioInButtomLeftChannel.Init.Input.Pins               = DFSDM_CHANNEL_SAME_CHANNEL_PINS;
01804     /* Request to sample stable data for LEFT micro on Rising edge */
01805     hAudioInButtomLeftChannel.Init.SerialInterface.Type     = DFSDM_CHANNEL_SPI_RISING;
01806     hAudioInButtomLeftChannel.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
01807     hAudioInButtomLeftChannel.Init.Awd.FilterOrder          = DFSDM_CHANNEL_FASTSINC_ORDER;
01808     hAudioInButtomLeftChannel.Init.Awd.Oversampling         = 10;
01809     hAudioInButtomLeftChannel.Init.Offset                   = 0;
01810     hAudioInButtomLeftChannel.Init.RightBitShift            = DFSDM_RIGHT_BIT_SHIFT(AudioFreq);
01811     if(HAL_OK != HAL_DFSDM_ChannelInit(&hAudioInButtomLeftChannel))
01812     {
01813       return AUDIO_ERROR;
01814     }
01815     
01816     /* CHANNEL 4 configuration */
01817     __HAL_DFSDM_CHANNEL_RESET_HANDLE_STATE(&hAudioInButtomRightChannel);  
01818     hAudioInButtomRightChannel.Instance                      = DFSDM1_Channel4;  
01819     hAudioInButtomRightChannel.Init.OutputClock.Activation   = ENABLE;
01820     hAudioInButtomRightChannel.Init.OutputClock.Selection    = DFSDM_CHANNEL_OUTPUT_CLOCK_AUDIO;
01821     /* Set the DFSDM clock OUT audio frequency configuration */
01822     hAudioInButtomRightChannel.Init.OutputClock.Divider      = DFSDM_CLOCK_DIVIDER(AudioFreq);
01823     hAudioInButtomRightChannel.Init.Input.Multiplexer        = DFSDM_CHANNEL_EXTERNAL_INPUTS;
01824     hAudioInButtomRightChannel.Init.Input.DataPacking        = DFSDM_CHANNEL_STANDARD_MODE;
01825     hAudioInButtomRightChannel.Init.Input.Pins               = DFSDM_CHANNEL_FOLLOWING_CHANNEL_PINS;
01826     /* Request to sample stable data for RIGHT micro on Falling edge */
01827     hAudioInButtomRightChannel.Init.SerialInterface.Type     = DFSDM_CHANNEL_SPI_FALLING;
01828     hAudioInButtomRightChannel.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
01829     hAudioInButtomRightChannel.Init.Awd.FilterOrder          = DFSDM_CHANNEL_FASTSINC_ORDER;
01830     hAudioInButtomRightChannel.Init.Awd.Oversampling         = 10;
01831     hAudioInButtomRightChannel.Init.Offset                   = 0;
01832     hAudioInButtomRightChannel.Init.RightBitShift            = DFSDM_RIGHT_BIT_SHIFT(AudioFreq);
01833     if(HAL_OK != HAL_DFSDM_ChannelInit(&hAudioInButtomRightChannel))
01834     {
01835       return AUDIO_ERROR;
01836     }
01837   }
01838   /****************************************************************************/ 
01839   /********************** Filters configuration  ******************************/
01840   /****************************************************************************/
01841   
01842   /* FILTER 0 configuration */
01843   __HAL_DFSDM_FILTER_RESET_HANDLE_STATE(&hAudioInTopLeftFilter);
01844   hAudioInTopLeftFilter.Instance                          = AUDIO_DFSDMx_TOP_LEFT_FILTER;  
01845   hAudioInTopLeftFilter.Init.RegularParam.Trigger         = DFSDM_FILTER_SW_TRIGGER;
01846   hAudioInTopLeftFilter.Init.RegularParam.FastMode        = ENABLE;
01847   hAudioInTopLeftFilter.Init.RegularParam.DmaMode         = ENABLE;
01848   hAudioInTopLeftFilter.Init.InjectedParam.Trigger        = DFSDM_FILTER_SW_TRIGGER;
01849   hAudioInTopLeftFilter.Init.InjectedParam.ScanMode       = ENABLE;
01850   hAudioInTopLeftFilter.Init.InjectedParam.DmaMode        = DISABLE;
01851   hAudioInTopLeftFilter.Init.InjectedParam.ExtTrigger     = DFSDM_FILTER_EXT_TRIG_TIM1_TRGO;
01852   hAudioInTopLeftFilter.Init.InjectedParam.ExtTriggerEdge = DFSDM_FILTER_EXT_TRIG_RISING_EDGE;
01853   hAudioInTopLeftFilter.Init.FilterParam.SincOrder        = DFSDM_FILTER_ORDER(AudioFreq);
01854   /* Set the DFSDM Filters Oversampling to have correct sample rate */
01855   hAudioInTopLeftFilter.Init.FilterParam.Oversampling     = DFSDM_OVER_SAMPLING(AudioFreq);
01856   hAudioInTopLeftFilter.Init.FilterParam.IntOversampling  = 1;
01857   if(HAL_OK != HAL_DFSDM_FilterInit(&hAudioInTopLeftFilter))
01858   {
01859     return AUDIO_ERROR;
01860   }
01861   
01862   /* Configure injected channel */
01863   if(HAL_OK != HAL_DFSDM_FilterConfigRegChannel(&hAudioInTopLeftFilter, AUDIO_DFSDMx_TOP_LEFT_CHANNEL, DFSDM_CONTINUOUS_CONV_ON))
01864   {
01865     return AUDIO_ERROR;
01866   }
01867   
01868   /* FILTER 1 configuration */
01869   __HAL_DFSDM_FILTER_RESET_HANDLE_STATE(&hAudioInTopRightFilter);
01870   hAudioInTopRightFilter.Instance                          = AUDIO_DFSDMx_TOP_RIGHT_FILTER;
01871   hAudioInTopRightFilter.Init.RegularParam.Trigger         = DFSDM_FILTER_SYNC_TRIGGER;
01872   hAudioInTopRightFilter.Init.RegularParam.FastMode        = ENABLE;
01873   hAudioInTopRightFilter.Init.RegularParam.DmaMode         = ENABLE;
01874   hAudioInTopRightFilter.Init.InjectedParam.Trigger        = DFSDM_FILTER_SW_TRIGGER;
01875   hAudioInTopRightFilter.Init.InjectedParam.ScanMode       = DISABLE;
01876   hAudioInTopRightFilter.Init.InjectedParam.DmaMode        = DISABLE;
01877   hAudioInTopRightFilter.Init.InjectedParam.ExtTrigger     = DFSDM_FILTER_EXT_TRIG_TIM1_TRGO;
01878   hAudioInTopRightFilter.Init.InjectedParam.ExtTriggerEdge = DFSDM_FILTER_EXT_TRIG_RISING_EDGE;
01879   hAudioInTopRightFilter.Init.FilterParam.SincOrder        = DFSDM_FILTER_ORDER(AudioFreq);
01880   /* Set the DFSDM Filters Oversampling to have correct sample rate */
01881   hAudioInTopRightFilter.Init.FilterParam.Oversampling     = DFSDM_OVER_SAMPLING(AudioFreq);
01882   hAudioInTopRightFilter.Init.FilterParam.IntOversampling  = 1;
01883   if(HAL_OK != HAL_DFSDM_FilterInit(&hAudioInTopRightFilter))
01884   {
01885     return AUDIO_ERROR;
01886   }
01887   /* Configure injected channel */
01888   if(HAL_OK != HAL_DFSDM_FilterConfigRegChannel(&hAudioInTopRightFilter, AUDIO_DFSDMx_TOP_RIGHT_CHANNEL, DFSDM_CONTINUOUS_CONV_ON))
01889   {
01890     return AUDIO_ERROR;
01891   } 
01892   
01893   if(AudioIn_ChannelNumber > 2)
01894   {
01895     /* FILTER 2 configuration */
01896     __HAL_DFSDM_FILTER_RESET_HANDLE_STATE(&hAudioInButtomLeftFilter);
01897     hAudioInButtomLeftFilter.Instance                          = AUDIO_DFSDMx_BUTTOM_LEFT_FILTER;  
01898     hAudioInButtomLeftFilter.Init.RegularParam.Trigger         = DFSDM_FILTER_SYNC_TRIGGER;
01899     hAudioInButtomLeftFilter.Init.RegularParam.FastMode        = ENABLE;
01900     hAudioInButtomLeftFilter.Init.RegularParam.DmaMode         = ENABLE;
01901     hAudioInButtomLeftFilter.Init.InjectedParam.Trigger        = DFSDM_FILTER_SW_TRIGGER;
01902     hAudioInButtomLeftFilter.Init.InjectedParam.ScanMode       = ENABLE;
01903     hAudioInButtomLeftFilter.Init.InjectedParam.DmaMode        = DISABLE;
01904     hAudioInButtomLeftFilter.Init.InjectedParam.ExtTrigger     = DFSDM_FILTER_EXT_TRIG_TIM1_TRGO;
01905     hAudioInButtomLeftFilter.Init.InjectedParam.ExtTriggerEdge = DFSDM_FILTER_EXT_TRIG_RISING_EDGE;
01906     hAudioInButtomLeftFilter.Init.FilterParam.SincOrder        = DFSDM_FILTER_ORDER(AudioFreq);
01907     /* Set the DFSDM Filters Oversampling to have correct sample rate */
01908     hAudioInButtomLeftFilter.Init.FilterParam.Oversampling     = DFSDM_OVER_SAMPLING(AudioFreq);
01909     hAudioInButtomLeftFilter.Init.FilterParam.IntOversampling  = 1;
01910     if(HAL_OK != HAL_DFSDM_FilterInit(&hAudioInButtomLeftFilter))
01911     {
01912       return AUDIO_ERROR;
01913     }
01914     
01915     /* Configure injected channel */
01916     if(HAL_OK != HAL_DFSDM_FilterConfigRegChannel(&hAudioInButtomLeftFilter, AUDIO_DFSDMx_BUTTOM_LEFT_CHANNEL, DFSDM_CONTINUOUS_CONV_ON))
01917     {
01918       return AUDIO_ERROR;
01919     }
01920     
01921     /* FILTER 3 configuration */
01922     __HAL_DFSDM_FILTER_RESET_HANDLE_STATE(&hAudioInButtomRightFilter);
01923     hAudioInButtomRightFilter.Instance                          = AUDIO_DFSDMx_BUTTOM_RIGHT_FILTER;
01924     hAudioInButtomRightFilter.Init.RegularParam.Trigger         = DFSDM_FILTER_SYNC_TRIGGER;
01925     hAudioInButtomRightFilter.Init.RegularParam.FastMode        = ENABLE;
01926     hAudioInButtomRightFilter.Init.RegularParam.DmaMode         = ENABLE;
01927     hAudioInButtomRightFilter.Init.InjectedParam.Trigger        = DFSDM_FILTER_SW_TRIGGER;
01928     hAudioInButtomRightFilter.Init.InjectedParam.ScanMode       = DISABLE;
01929     hAudioInButtomRightFilter.Init.InjectedParam.DmaMode        = DISABLE;
01930     hAudioInButtomRightFilter.Init.InjectedParam.ExtTrigger     = DFSDM_FILTER_EXT_TRIG_TIM1_TRGO;
01931     hAudioInButtomRightFilter.Init.InjectedParam.ExtTriggerEdge = DFSDM_FILTER_EXT_TRIG_RISING_EDGE;
01932     hAudioInButtomRightFilter.Init.FilterParam.SincOrder        = DFSDM_FILTER_ORDER(AudioFreq);
01933     /* Set the DFSDM Filters Oversampling to have correct sample rate */
01934     hAudioInButtomRightFilter.Init.FilterParam.Oversampling     = DFSDM_OVER_SAMPLING(AudioFreq);
01935     hAudioInButtomRightFilter.Init.FilterParam.IntOversampling  = 1;
01936     if(HAL_OK != HAL_DFSDM_FilterInit(&hAudioInButtomRightFilter))
01937     {
01938       return AUDIO_ERROR;
01939     }
01940     /* Configure injected channel */
01941     if(HAL_OK != HAL_DFSDM_FilterConfigRegChannel(&hAudioInButtomRightFilter, AUDIO_DFSDMx_BUTTOM_RIGHT_CHANNEL, DFSDM_CONTINUOUS_CONV_ON))
01942     {
01943       return AUDIO_ERROR;
01944     } 
01945   }
01946   return AUDIO_OK;
01947 }
01948 
01949 /**
01950   * @brief  De-initialize the Digital Filter for Sigma-Delta Modulators interface (DFSDM).
01951   * @retval AUDIO_OK if correct communication, else wrong communication
01952   */
01953 static uint8_t DFSDMx_DeInit(void)
01954 {  
01955   /* De-initializes the DFSDM filters to allow access to DFSDM internal registers */
01956   if(HAL_OK != HAL_DFSDM_FilterDeInit(&hAudioInTopLeftFilter))
01957   {
01958     return AUDIO_ERROR;
01959   }
01960   
01961   if(HAL_OK != HAL_DFSDM_FilterDeInit(&hAudioInTopRightFilter))
01962   {
01963     return AUDIO_ERROR;
01964   }
01965   
01966   /* De-initializes the DFSDM channels to allow access to DFSDM internal registers */
01967   if(HAL_OK != HAL_DFSDM_ChannelDeInit(&hAudioInTopLeftChannel))
01968   {
01969     return AUDIO_ERROR;
01970   }
01971   
01972   if(HAL_OK != HAL_DFSDM_ChannelDeInit(&hAudioInTopRightChannel))
01973   {
01974     return AUDIO_ERROR;
01975   }
01976 
01977   if(AudioIn_ChannelNumber > 2)
01978   {
01979     /* De-initializes the DFSDM filters to allow access to DFSDM internal registers */        
01980     if(HAL_OK != HAL_DFSDM_FilterDeInit(&hAudioInButtomLeftFilter))
01981     {
01982       return AUDIO_ERROR;
01983     }
01984     
01985     if(HAL_OK != HAL_DFSDM_FilterDeInit(&hAudioInButtomRightFilter))
01986     {
01987       return AUDIO_ERROR;
01988     }
01989     
01990     /* De-initializes the DFSDM channels to allow access to DFSDM internal registers */  
01991     if(HAL_OK != HAL_DFSDM_ChannelDeInit(&hAudioInButtomLeftChannel))
01992     {
01993       return AUDIO_ERROR;
01994     }
01995     
01996     if(HAL_OK != HAL_DFSDM_ChannelDeInit(&hAudioInButtomRightChannel))
01997     {
01998       return AUDIO_ERROR;
01999     }  
02000   }
02001   
02002   return AUDIO_OK;
02003 }
02004 
02005 /**
02006   * @brief  Initialize the DFSDM channel MSP.
02007   * @retval None
02008   */
02009 static void DFSDMx_ChannelMspInit(void)
02010 {
02011   GPIO_InitTypeDef  GPIO_InitStruct;  
02012   
02013   /* Enable DFSDM clock */
02014   AUDIO_DFSDMx_CLK_ENABLE();
02015   
02016   /* Enable GPIO clock */
02017   AUDIO_DFSDMx_DMIC_DATIN_GPIO_CLK_ENABLE();
02018   AUDIO_DFSDMx_CKOUT_DMIC_GPIO_CLK_ENABLE();
02019   
02020   /* DFSDM pins configuration: DFSDM_CKOUT, DMIC_DATIN1 pins ------------------*/
02021   GPIO_InitStruct.Pin = AUDIO_DFSDMx_CKOUT_PIN;
02022   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
02023   GPIO_InitStruct.Pull = GPIO_NOPULL;
02024   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
02025   GPIO_InitStruct.Alternate = AUDIO_DFSDMx_CKOUT_AF;
02026   HAL_GPIO_Init(AUDIO_DFSDMx_CKOUT_DMIC_GPIO_PORT, &GPIO_InitStruct);
02027   
02028   /* DFSDM pin configuration: DMIC_DATIN1 pin --------------------------------*/
02029   GPIO_InitStruct.Pin = AUDIO_DFSDMx_DMIC_DATIN1_PIN;
02030   GPIO_InitStruct.Alternate = AUDIO_DFSDMx_DMIC_DATIN_AF;
02031   HAL_GPIO_Init(AUDIO_DFSDMx_DMIC_DATIN_GPIO_PORT, &GPIO_InitStruct);
02032   
02033   if(AudioIn_ChannelNumber > 2)
02034   {
02035   /* DFSDM pin configuration: DMIC_DATIN5 pin --------------------------------*/  
02036     GPIO_InitStruct.Pin = AUDIO_DFSDMx_DMIC_DATIN5_PIN;
02037     GPIO_InitStruct.Alternate = AUDIO_DFSDMx_DMIC_DATIN_AF;
02038     HAL_GPIO_Init(AUDIO_DFSDMx_DMIC_DATIN_GPIO_PORT, &GPIO_InitStruct);    
02039   }
02040 }
02041 
02042 /**
02043   * @brief  DeInitialize the DFSDM channel MSP.
02044   * @retval None
02045   */
02046 static void DFSDMx_ChannelMspDeInit(void)
02047 {
02048   GPIO_InitTypeDef  GPIO_InitStruct;  
02049   
02050   /* DFSDM pin configuration: DMIC_DATIN1 pin --------------------------------*/
02051   GPIO_InitStruct.Pin = AUDIO_DFSDMx_CKOUT_PIN;
02052   HAL_GPIO_DeInit(AUDIO_DFSDMx_CKOUT_DMIC_GPIO_PORT, GPIO_InitStruct.Pin);
02053   GPIO_InitStruct.Pin = AUDIO_DFSDMx_DMIC_DATIN1_PIN;
02054   HAL_GPIO_DeInit(AUDIO_DFSDMx_DMIC_DATIN_GPIO_PORT, GPIO_InitStruct.Pin);
02055   
02056   if(AudioIn_ChannelNumber > 2)
02057   {
02058     /* DFSDM pin configuration: DMIC_DATIN5 pin ------------------------------*/
02059     GPIO_InitStruct.Pin = AUDIO_DFSDMx_CKOUT_PIN;
02060     HAL_GPIO_DeInit(AUDIO_DFSDMx_CKOUT_DMIC_GPIO_PORT, GPIO_InitStruct.Pin);
02061     GPIO_InitStruct.Pin = AUDIO_DFSDMx_DMIC_DATIN5_PIN;
02062     HAL_GPIO_DeInit(AUDIO_DFSDMx_DMIC_DATIN_GPIO_PORT, GPIO_InitStruct.Pin);    
02063   }
02064 }
02065 
02066 /**
02067   * @brief  Initialize the DFSDM filter MSP.
02068   * @retval None
02069   */
02070 static void DFSDMx_FilterMspInit(void)
02071 {  
02072   /* Enable DFSDM clock */
02073   AUDIO_DFSDMx_CLK_ENABLE();
02074   
02075   /* Enable the DMA clock */
02076   AUDIO_DFSDMx_DMAx_CLK_ENABLE();
02077   
02078   /*********** Configure DMA stream for TOP LEFT microphone *******************/
02079   hDmaTopLeft.Init.Direction           = DMA_PERIPH_TO_MEMORY;
02080   hDmaTopLeft.Init.PeriphInc           = DMA_PINC_DISABLE;
02081   hDmaTopLeft.Init.MemInc              = DMA_MINC_ENABLE;
02082   hDmaTopLeft.Init.PeriphDataAlignment = AUDIO_DFSDMx_DMAx_PERIPH_DATA_SIZE;
02083   hDmaTopLeft.Init.MemDataAlignment    = AUDIO_DFSDMx_DMAx_MEM_DATA_SIZE;
02084   hDmaTopLeft.Init.Mode                = DMA_CIRCULAR;
02085   hDmaTopLeft.Init.Priority            = DMA_PRIORITY_HIGH;
02086   hDmaTopLeft.Instance                 = AUDIO_DFSDMx_DMAx_TOP_LEFT_STREAM;
02087   hDmaTopLeft.Init.Channel             = AUDIO_DFSDMx_DMAx_CHANNEL; 
02088   
02089   /* Associate the DMA handle */
02090   __HAL_LINKDMA(&hAudioInTopLeftFilter, hdmaReg, hDmaTopLeft);
02091   
02092   /* Reset DMA handle state */
02093   __HAL_DMA_RESET_HANDLE_STATE(&hDmaTopLeft);
02094   
02095   /* Configure the DMA Channel */
02096   HAL_DMA_Init(&hDmaTopLeft);      
02097   
02098   /* DMA IRQ Channel configuration */
02099   HAL_NVIC_SetPriority(AUDIO_DFSDMx_DMAx_TOP_LEFT_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0);
02100   HAL_NVIC_EnableIRQ(AUDIO_DFSDMx_DMAx_TOP_LEFT_IRQ);
02101   
02102   
02103   /*********** Configure DMA stream for TOP RIGHT microphone ******************/
02104   hDmaTopRight.Init.Direction           = DMA_PERIPH_TO_MEMORY;
02105   hDmaTopRight.Init.PeriphInc           = DMA_PINC_DISABLE;
02106   hDmaTopRight.Init.MemInc              = DMA_MINC_ENABLE;
02107   hDmaTopRight.Init.PeriphDataAlignment = AUDIO_DFSDMx_DMAx_PERIPH_DATA_SIZE;
02108   hDmaTopRight.Init.MemDataAlignment    = AUDIO_DFSDMx_DMAx_MEM_DATA_SIZE;
02109   hDmaTopRight.Init.Mode                = DMA_CIRCULAR;
02110   hDmaTopRight.Init.Priority            = DMA_PRIORITY_HIGH;  
02111   hDmaTopRight.Instance                 = AUDIO_DFSDMx_DMAx_TOP_RIGHT_STREAM;
02112   hDmaTopRight.Init.Channel             = AUDIO_DFSDMx_DMAx_CHANNEL;
02113   
02114   /* Associate the DMA handle */
02115   __HAL_LINKDMA(&hAudioInTopRightFilter, hdmaReg, hDmaTopRight);
02116   
02117   /* Reset DMA handle state */
02118   __HAL_DMA_RESET_HANDLE_STATE(&hDmaTopRight);
02119   
02120   /* Configure the DMA Channel */
02121   HAL_DMA_Init(&hDmaTopRight);      
02122   
02123   /* DMA IRQ Channel configuration */
02124   HAL_NVIC_SetPriority(AUDIO_DFSDMx_DMAx_TOP_RIGHT_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0);
02125   HAL_NVIC_EnableIRQ(AUDIO_DFSDMx_DMAx_TOP_RIGHT_IRQ);
02126   
02127   if(AudioIn_ChannelNumber > 2)
02128   {  
02129     /*********** Configure DMA stream for BUTTOM LEFT microphone ****************/
02130     hDmaButtomLeft.Init.Direction           = DMA_PERIPH_TO_MEMORY;
02131     hDmaButtomLeft.Init.PeriphInc           = DMA_PINC_DISABLE;
02132     hDmaButtomLeft.Init.MemInc              = DMA_MINC_ENABLE;
02133     hDmaButtomLeft.Init.PeriphDataAlignment = AUDIO_DFSDMx_DMAx_PERIPH_DATA_SIZE;
02134     hDmaButtomLeft.Init.MemDataAlignment    = AUDIO_DFSDMx_DMAx_MEM_DATA_SIZE;
02135     hDmaButtomLeft.Init.Mode                = DMA_CIRCULAR;
02136     hDmaButtomLeft.Init.Priority            = DMA_PRIORITY_HIGH;
02137     hDmaButtomLeft.Instance                 = AUDIO_DFSDMx_DMAx_BUTTOM_LEFT_STREAM;
02138     hDmaButtomLeft.Init.Channel             = AUDIO_DFSDMx_DMAx_CHANNEL; 
02139     
02140     /* Associate the DMA handle */
02141     __HAL_LINKDMA(&hAudioInButtomLeftFilter, hdmaReg, hDmaButtomLeft);
02142     
02143     /* Reset DMA handle state */
02144     __HAL_DMA_RESET_HANDLE_STATE(&hDmaButtomLeft);
02145     
02146     /* Configure the DMA Channel */
02147     HAL_DMA_Init(&hDmaButtomLeft);      
02148     
02149     /* DMA IRQ Channel configuration */
02150     HAL_NVIC_SetPriority(AUDIO_DFSDMx_DMAx_BUTTOM_LEFT_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0);
02151     HAL_NVIC_EnableIRQ(AUDIO_DFSDMx_DMAx_BUTTOM_LEFT_IRQ);
02152     
02153     
02154     /*********** Configure DMA stream for BUTTOM RIGHT microphone ***************/
02155     hDmaButtomRight.Init.Direction           = DMA_PERIPH_TO_MEMORY;
02156     hDmaButtomRight.Init.PeriphInc           = DMA_PINC_DISABLE;
02157     hDmaButtomRight.Init.MemInc              = DMA_MINC_ENABLE;
02158     hDmaButtomRight.Init.PeriphDataAlignment = AUDIO_DFSDMx_DMAx_PERIPH_DATA_SIZE;
02159     hDmaButtomRight.Init.MemDataAlignment    = AUDIO_DFSDMx_DMAx_MEM_DATA_SIZE;
02160     hDmaButtomRight.Init.Mode                = DMA_CIRCULAR;
02161     hDmaButtomRight.Init.Priority            = DMA_PRIORITY_HIGH;  
02162     hDmaButtomRight.Instance                 = AUDIO_DFSDMx_DMAx_BUTTOM_RIGHT_STREAM;
02163     hDmaButtomRight.Init.Channel             = AUDIO_DFSDMx_DMAx_CHANNEL;
02164     
02165     /* Associate the DMA handle */
02166     __HAL_LINKDMA(&hAudioInButtomRightFilter, hdmaReg, hDmaButtomRight);
02167     
02168     /* Reset DMA handle state */
02169     __HAL_DMA_RESET_HANDLE_STATE(&hDmaButtomRight);
02170     
02171     /* Configure the DMA Channel */
02172     HAL_DMA_Init(&hDmaButtomRight);      
02173     
02174     /* DMA IRQ Channel configuration */
02175     HAL_NVIC_SetPriority(AUDIO_DFSDMx_DMAx_BUTTOM_RIGHT_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0);
02176     HAL_NVIC_EnableIRQ(AUDIO_DFSDMx_DMAx_BUTTOM_RIGHT_IRQ); 
02177   }
02178 }
02179 
02180 /**
02181   * @brief  DeInitialize the DFSDM filter MSP.
02182   * @retval None
02183   */
02184 static void DFSDMx_FilterMspDeInit(void)
02185 {
02186   /* Configure the DMA Channel */
02187   HAL_DMA_DeInit(&hDmaTopLeft);
02188   HAL_DMA_DeInit(&hDmaTopRight);
02189   if(AudioIn_ChannelNumber > 2)
02190   {
02191     HAL_DMA_DeInit(&hDmaButtomLeft);
02192     HAL_DMA_DeInit(&hDmaButtomRight);
02193   }  
02194 }
02195 
02196 /**
02197   * @brief  This function handles DMA2 Stream 0 interrupt request.
02198   * @param  None
02199   * @retval None
02200   */
02201 void AUDIO_DFSDMx_DMAx_TOP_LEFT_IRQHandler(void) // DMA2_Stream0_IRQHandler
02202 {
02203     HAL_DMA_IRQHandler(hAudioInTopLeftFilter.hdmaReg);
02204 }
02205 
02206 /**
02207   * @brief  This function handles DMA2 Stream 5 interrupt request.
02208   * @param  None
02209   * @retval None
02210   */
02211 void AUDIO_DFSDMx_DMAx_TOP_RIGHT_IRQHandler(void) // DMA2_Stream5_IRQHandler
02212 {
02213    HAL_DMA_IRQHandler(hAudioInTopRightFilter.hdmaReg); 
02214 }
02215 
02216 /**
02217   * @brief  This function handles DMA2 Stream 1 interrupt request.
02218   * @param  None
02219   * @retval None
02220   */
02221 void AUDIO_OUT_SAIx_DMAx_IRQHandler(void) // DMA2_Stream1_IRQHandler
02222 {
02223   HAL_DMA_IRQHandler(haudio_out_sai.hdmatx);
02224 }
02225 
02226 /**
02227   * @brief  This function handles DMA2 Stream 6 interrupt request.
02228   * @param  None
02229   * @retval None
02230   */
02231 void AUDIO_DFSDMx_DMAx_BUTTOM_LEFT_IRQHandler(void) // DMA2_Stream6_IRQHandler
02232 {
02233   HAL_DMA_IRQHandler(hAudioInButtomLeftFilter.hdmaReg);
02234 }
02235 
02236 /**
02237   * @brief  This function handles DMA2 Stream 7 interrupt request.
02238   * @param  None
02239   * @retval None
02240   */
02241 void AUDIO_DFSDMx_DMAx_BUTTOM_RIGHT_IRQHandler(void) // DMA2_Stream7_IRQHandler
02242 {
02243   HAL_DMA_IRQHandler(hAudioInButtomRightFilter.hdmaReg);
02244 }
02245 
02246 
02247 /**
02248   * @}
02249   */ 
02250   
02251 /**
02252   * @}
02253   */
02254 
02255 /**
02256   * @}
02257   */
02258 
02259 /**
02260   * @}
02261   */ 
02262 
02263 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/