STM32469I-Discovery BSP User Manual: stm32469i_discovery_audio.c Source File

STM32469I-Discovery BSP Drivers

stm32469i_discovery_audio.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32469i_discovery_audio.c
00004   * @author  MCD Application Team
00005   * @version V2.0.0
00006   * @date    31-January-2017
00007   * @brief   This file provides the Audio driver for the STM32469I-Discovery board.
00008   ******************************************************************************
00009   * @attention
00010   *
00011   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
00012   *
00013   * Redistribution and use in source and binary forms, with or without modification,
00014   * are permitted provided that the following conditions are met:
00015   *   1. Redistributions of source code must retain the above copyright notice,
00016   *      this list of conditions and the following disclaimer.
00017   *   2. Redistributions in binary form must reproduce the above copyright notice,
00018   *      this list of conditions and the following disclaimer in the documentation
00019   *      and/or other materials provided with the distribution.
00020   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00021   *      may be used to endorse or promote products derived from this software
00022   *      without specific prior written permission.
00023   *
00024   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00025   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00026   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00028   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00029   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00030   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00032   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00033   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034   *
00035   ******************************************************************************
00036   */
00037 
00038 /*==============================================================================
00039                                  User NOTES
00040 
00041 How To use this driver:
00042 -----------------------
00043    + This driver supports STM32F4xx devices on STM32469I-Discovery (MB1189) Discovery boards.
00044    + Call the function BSP_AUDIO_OUT_Init(
00045                                     OutputDevice: physical output mode (OUTPUT_DEVICE_HEADPHONE1,
00046                                                   OUTPUT_DEVICE_HEADPHONE2 or OUTPUT_DEVICE_BOTH)
00047                                     Volume      : Initial volume to be set (0 is min (mute), 100 is max (100%)
00048                                     AudioFreq   : Audio frequency in Hz (8000, 16000, 22500, 32000...)
00049                                                   this parameter is relative to the audio file/stream type.
00050                                    )
00051       This function configures all the hardware required for the audio application (codec, I2C, SAI,
00052       GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if configuration is OK.
00053       If the returned value is different from AUDIO_OK or the function is stuck then the communication with
00054       the codec or the MFX has failed (try to un-plug the power or reset device in this case).
00055       - OUTPUT_DEVICE_HEADPHONE1 : only headphones 1 will be set as output for the audio stream.
00056       - OUTPUT_DEVICE_HEADPHONE2 : only headphones 2 will be set as output for the audio stream.
00057       - OUTPUT_DEVICE_BOTH       : both Headphones are used as outputs for the audio stream
00058                                  at the same time.
00059       Note. On STM32469I-Discovery SAI_DMA is configured in CIRCULAR mode. Due to this the application
00060         does NOT need to call BSP_AUDIO_OUT_ChangeBuffer() to assure straming.
00061    + Call the function BSP_Discovery_AUDIO_OUT_Play(
00062                                   pBuffer: pointer to the audio data file address
00063                                   Size   : size of the buffer to be sent in Bytes
00064                                  )
00065       to start playing (for the first time) from the audio file/stream.
00066    + Call the function BSP_AUDIO_OUT_Pause() to pause playing
00067    + Call the function BSP_AUDIO_OUT_Resume() to resume playing.
00068        Note. After calling BSP_AUDIO_OUT_Pause() function for pause, only BSP_AUDIO_OUT_Resume() should be called
00069           for resume (it is not allowed to call BSP_AUDIO_OUT_Play() in this case).
00070        Note. This function should be called only when the audio file is played or paused (not stopped).
00071    + For each mode, you may need to implement the relative callback functions into your code.
00072       The Callback functions are named AUDIO_OUT_XXX_CallBack() and only their prototypes are declared in
00073       the stm32469i_discovery_audio.h file. (refer to the example for more details on the callbacks implementations)
00074    + To Stop playing, to modify the volume level, the frequency, the audio frame slot,
00075       the device output mode the mute or the stop, use the functions: BSP_AUDIO_OUT_SetVolume(),
00076       AUDIO_OUT_SetFrequency(), BSP_AUDIO_OUT_SetAudioFrameSlot(), BSP_AUDIO_OUT_SetOutputMode(),
00077       BSP_AUDIO_OUT_SetMute() and BSP_AUDIO_OUT_Stop().
00078    + The driver API and the callback functions are at the end of the stm32469i_discovery_audio.h file.
00079 
00080 Driver architecture:
00081 --------------------
00082    + This driver provide the High Audio Layer: consists of the function API exported in the stm32469i_discovery_audio.h file
00083      (BSP_AUDIO_OUT_Init(), BSP_AUDIO_OUT_Play() ...)
00084    + This driver provide also the Media Access Layer (MAL): which consists of functions allowing to access the media containing/
00085      providing the audio file/stream. These functions are also included as local functions into
00086      the stm32469i_discovery_audio_codec.c file (I2Sx_Init(), I2Sx_DeInit(), SAIx_Init() and SAIx_DeInit())
00087 
00088 Known Limitations:
00089 ------------------
00090    1- If the TDM Format used to paly in parallel 2 audio Stream (the first Stream is configured in codec SLOT0 and second
00091       Stream in SLOT1) the Pause/Resume, volume and mute feature will control the both streams.
00092    2- Parsing of audio file is not implemented (in order to determine audio file properties: Mono/Stereo, Data size,
00093       File size, Audio Frequency, Audio Data header size ...). The configuration is fixed for the given audio file.
00094    3- Supports only Stereo audio streaming.
00095    4- Supports only 16-bits audio data size.
00096 ==============================================================================*/
00097 
00098 /* Includes ------------------------------------------------------------------*/
00099 #include <string.h>
00100 #include "stm32469i_discovery_audio.h"
00101 
00102 /** @addtogroup BSP
00103   * @{
00104   */
00105 
00106 /** @addtogroup STM32469I_Discovery
00107   * @{
00108   */
00109 
00110 /** @defgroup STM32469I-Discovery_AUDIO STM32469I Discovery AUDIO
00111   * @brief This file includes the low layer driver for CS43L22 Audio Codec
00112   *        available on STM32469I-Discovery board(MB1189).
00113   * @{
00114   */
00115 
00116 /** @defgroup STM32469I-Discovery_AUDIO_Private_Types STM32469I Discovery AUDIO Private Types
00117   * @{
00118   */
00119 /**
00120   * @}
00121   */
00122 
00123 /** @defgroup STM32469I-Discovery_AUDIO_Private_Defines STM32469I Discovery AUDIO Private Defines
00124  *  @brief Headphone1 (CN27 of STM32469I-Discovery board) is connected to the
00125  *         HEADPHONE output of CS43L22 Audio Codec.
00126  *         Headphone2 (CN26 of STM32469I-Discovery board) is connected to the
00127  *         SPEAKER output of CS43L22 Audio Codec.
00128   * @{
00129   */
00130 #define OUTPUT_DEVICE_HEADPHONE1 OUTPUT_DEVICE_HEADPHONE
00131 
00132 /* Headphone2 is connected to Speaker output of the CS43L22 codec */
00133 #define OUTPUT_DEVICE_HEADPHONE2 OUTPUT_DEVICE_SPEAKER
00134 /**
00135   * @}
00136   */
00137 
00138 /** @defgroup STM32469I-Discovery_AUDIO_Private_Macros STM32469I Discovery AUDIO Private macros
00139   * @{
00140   */
00141 
00142 /*### PLAY ###*/
00143 /* SCK(kHz) = SAI_CK_x/(SAIClockDivider*2*256) */
00144 #define SAIClockDivider(__FREQUENCY__) \
00145         (__FREQUENCY__ == AUDIO_FREQUENCY_8K)  ? 12 \
00146       : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 2 \
00147       : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 6 \
00148       : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 1 \
00149       : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 3 \
00150       : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 0 \
00151       : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 2 : 1  \
00152 
00153 /**
00154   * @}
00155   */
00156 
00157 /** @defgroup STM32469I-Discovery_AUDIO_Private_Variables STM32469I Discovery AUDIO Private Variables
00158   * @{
00159   */
00160   
00161 /*
00162 Note: 
00163   these global variables are not compliant to naming rules (upper case without "_" ), 
00164   but we keep this naming for compatibility, in fact these variables (not static)
00165   could have been used by the application, example the stm32f4xx_it.c:
00166     void DMA2_Stream6_IRQHandler(void)
00167      {  HAL_DMA_IRQHandler(haudio_out_sai.hdmatx);  }
00168 */
00169 AUDIO_DrvTypeDef          *audio_drv;
00170 SAI_HandleTypeDef         haudio_out_sai;
00171 I2S_HandleTypeDef         haudio_in_i2s;
00172 TIM_HandleTypeDef         haudio_tim;
00173 
00174 PDMFilter_InitStruct Filter[2];
00175 uint8_t Channel_Demux[128] = {
00176     0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
00177     0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
00178     0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
00179     0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
00180     0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
00181     0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
00182     0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
00183     0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
00184     0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
00185     0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
00186     0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f,
00187     0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f,
00188     0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
00189     0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
00190     0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f,
00191     0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f
00192 };
00193 
00194 uint16_t __IO AudioInVolume = DEFAULT_AUDIO_IN_VOLUME;
00195 
00196 /**
00197   * @}
00198   */
00199 
00200 /** @defgroup STM32469I-Discovery_AUDIO_Private_Function_Prototypes STM32469I Discovery AUDIO Private Prototypes
00201   * @{
00202   */
00203 static uint8_t SAIx_Init(uint32_t AudioFreq);
00204 static void SAIx_DeInit(void);
00205 static void I2Sx_Init(uint32_t AudioFreq);
00206 static void I2Sx_DeInit(void);
00207 static void TIMx_IC_MspInit(TIM_HandleTypeDef *htim);
00208 static void TIMx_IC_MspDeInit(TIM_HandleTypeDef *htim);
00209 static void TIMx_Init(void);
00210 static void TIMx_DeInit(void);
00211 static void PDMDecoder_Init(uint32_t AudioFreq, uint32_t ChnlNbr);
00212 
00213 void BSP_AUDIO_OUT_ChangeAudioConfig(uint32_t AudioOutOption);
00214 
00215 /**
00216   * @}
00217   */
00218 
00219 /** @defgroup STM32469I-Discovery_AUDIO_out_Private_Functions STM32469I Discovery AUDIO OUT Private Functions
00220   * @{
00221   */
00222 
00223 /**
00224   * @brief  Configures the audio peripherals.
00225   * @param  OutputDevice: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
00226   *                       or OUTPUT_DEVICE_BOTH.
00227   * @param  Volume: Initial volume level (from 0 (Mute) to 100 (Max))
00228   * @param  AudioFreq: Audio frequency used to play the audio stream.
00229   * @note   The SAI PLL input clock must be done in the user application.  
00230   * @retval AUDIO_OK if correct communication, else wrong communication
00231   */
00232 uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, 
00233                            uint8_t Volume, 
00234                            uint32_t AudioFreq)
00235 {
00236   uint8_t ret = AUDIO_OK;
00237 
00238   SAIx_DeInit();
00239   
00240   /* PLL clock is set depending by the AudioFreq (44.1khz vs 48khz groups) */ 
00241   BSP_AUDIO_OUT_ClockConfig(&haudio_out_sai, AudioFreq, NULL);
00242 
00243   /* SAI data transfer preparation:
00244   Prepare the Media to be used for the audio transfer from memory to SAI peripheral */
00245   haudio_out_sai.Instance = AUDIO_SAIx;
00246   if(HAL_SAI_GetState(&haudio_out_sai) == HAL_SAI_STATE_RESET)
00247   {
00248     /* Init the SAI MSP: this __weak function can be redefined by the application*/
00249     BSP_AUDIO_OUT_MspInit(&haudio_out_sai, NULL);
00250   }
00251 
00252   if (SAIx_Init(AudioFreq) != AUDIO_OK)
00253   {
00254     ret = AUDIO_ERROR;
00255   }
00256 
00257   if(ret == AUDIO_OK)
00258   {
00259     /* Retieve audio codec identifier */
00260     if (cs43l22_drv.ReadID(AUDIO_I2C_ADDRESS) == CS43L22_ID)
00261     {  
00262       /* Initialize the audio driver structure */
00263       audio_drv = &cs43l22_drv;
00264     }
00265     else
00266     {
00267       ret = AUDIO_ERROR;
00268     }
00269   }
00270 
00271   if(ret == AUDIO_OK)
00272   {
00273     /* Initialize the audio codec internal registers */
00274     if (audio_drv->Init(AUDIO_I2C_ADDRESS,
00275                         OutputDevice, 
00276                         Volume, 
00277                         AudioFreq) != AUDIO_OK)
00278     {
00279       ret = AUDIO_ERROR;
00280     }
00281   }
00282 
00283   return ret;
00284 }
00285 
00286 /**
00287   * @brief  Starts playing audio stream from a data buffer for a determined size.
00288   * @param  pBuffer: Pointer to the buffer
00289   * @param  Size: Number of audio data BYTES.
00290   * @retval AUDIO_OK if correct communication, else wrong communication
00291   */
00292 uint8_t BSP_AUDIO_OUT_Play(uint16_t* pBuffer, uint32_t Size)
00293 {
00294   uint8_t ret = AUDIO_OK;
00295 
00296   /* Call the audio Codec Play function */
00297   if(audio_drv->Play(AUDIO_I2C_ADDRESS, pBuffer, Size) != 0)
00298   {  
00299     ret = AUDIO_ERROR;
00300   }
00301 
00302   /* Initiate a DMA transfer of PCM samples towards the serial audio interface */  
00303   if(ret == AUDIO_OK)
00304   {
00305     if (HAL_SAI_Transmit_DMA(&haudio_out_sai, (uint8_t*) pBuffer, DMA_MAX(Size / AUDIODATA_SIZE))!= HAL_OK)
00306     {
00307       ret = AUDIO_ERROR;
00308     }
00309   }
00310         
00311   return ret;
00312 }
00313 
00314 /**
00315   * @brief  Sends n-Bytes on the SAI interface.
00316   * @param  pData: pointer on PCM samples buffer 
00317   * @param  Size: number of data to be written
00318   */
00319 void BSP_AUDIO_OUT_ChangeBuffer(uint16_t *pData, uint16_t Size)
00320 {
00321    HAL_SAI_Transmit_DMA(&haudio_out_sai, (uint8_t*) pData, Size);
00322 }
00323 
00324 /**
00325   * @brief   This function Pauses the audio file stream. In case
00326   *          of using DMA, the DMA Pause feature is used.
00327   * @warning When calling BSP_AUDIO_OUT_Pause() function for pause, only
00328   *          BSP_AUDIO_OUT_Resume() function should be called for resume (use of BSP_AUDIO_OUT_Play()
00329   *          function for resume could lead to unexpected behavior).
00330   * @retval  AUDIO_OK if correct communication, else wrong communication
00331   */
00332 uint8_t BSP_AUDIO_OUT_Pause(void)
00333 {
00334   uint8_t ret = AUDIO_OK;
00335 
00336   /* Call the Audio Codec Pause/Resume function */
00337   if(audio_drv->Pause(AUDIO_I2C_ADDRESS) != 0)
00338   {
00339     ret =  AUDIO_ERROR;
00340   }
00341  
00342   /* Pause DMA transfer of PCM samples towards the serial audio interface */  
00343   if(ret == AUDIO_OK)
00344   {
00345     if (HAL_SAI_DMAPause(&haudio_out_sai)!= HAL_OK)
00346     {
00347       ret =  AUDIO_ERROR;
00348     }
00349   }
00350 
00351   /* Return AUDIO_OK when all operations are correctly done */
00352   return ret;
00353 }
00354 
00355 /**
00356   * @brief  This function  Resumes the audio file stream.
00357   * WARNING: When calling BSP_AUDIO_OUT_Pause() function for pause, only
00358   *          BSP_AUDIO_OUT_Resume() function should be called for resume
00359   *          (use of BSP_AUDIO_OUT_Play() function for resume could lead to 
00360   *           unexpected behavior).
00361   * @retval AUDIO_OK if correct communication, else wrong communication
00362   */
00363 uint8_t BSP_AUDIO_OUT_Resume(void)
00364 {
00365   uint8_t ret = AUDIO_OK;
00366 
00367   /* Call the Audio Codec Pause/Resume function */
00368   if(audio_drv->Resume(AUDIO_I2C_ADDRESS) != 0)
00369   {
00370     ret =  AUDIO_ERROR;
00371   }
00372 
00373   /* Resume DMA transfer of PCM samples towards the serial audio interface */  
00374   if(ret == AUDIO_OK)
00375   {
00376     if (HAL_SAI_DMAResume(&haudio_out_sai)!= HAL_OK)
00377     {
00378       ret =  AUDIO_ERROR;
00379     }
00380   }
00381 
00382   /* Return AUDIO_OK when all operations are correctly done */
00383   return ret;
00384 }
00385 
00386 /**
00387   * @brief  Stops audio playing and Power down the Audio Codec.
00388   * @param  Option: could be one of the following parameters
00389   *           - CODEC_PDWN_SW: for software power off (by writing registers).
00390   *                            Then no need to reconfigure the Codec after power on.
00391   *           - CODEC_PDWN_HW: completely shut down the codec (physically).
00392   *                            Then need to reconfigure the Codec after power on.
00393   * @retval AUDIO_OK if correct communication, else wrong communication
00394   */
00395 uint8_t BSP_AUDIO_OUT_Stop(uint32_t Option)
00396 {
00397   uint8_t ret = AUDIO_OK;
00398 
00399  /* Call Audio Codec Stop function */
00400   if(audio_drv->Stop(AUDIO_I2C_ADDRESS, Option) != 0)
00401   {
00402     ret = AUDIO_ERROR;
00403   }
00404 
00405   if(ret == AUDIO_OK)
00406   {
00407     if(Option == CODEC_PDWN_HW)
00408     {
00409       /* Wait at least 100us */
00410       HAL_Delay(2);
00411     }
00412 
00413     /* Stop DMA transfer of PCM samples towards the serial audio interface */  
00414     if (HAL_SAI_DMAStop(&haudio_out_sai)!= HAL_OK)
00415     {
00416       ret = AUDIO_ERROR;
00417     }
00418   }
00419   /* Return AUDIO_OK when all operations are correctly done */
00420   return ret;
00421 }
00422 
00423 /**
00424   * @brief  Controls the current audio volume level.
00425   * @param  Volume: Volume level to be set in percentage from 0% to 100% (0 for
00426   *         Mute and 100 for Max volume level).
00427   * @retval AUDIO_OK if correct communication, else wrong communication
00428   */
00429 uint8_t BSP_AUDIO_OUT_SetVolume(uint8_t Volume)
00430 {
00431   uint8_t ret = AUDIO_OK;
00432 
00433   /* Call the codec volume control function with converted volume value */
00434   if(audio_drv->SetVolume(AUDIO_I2C_ADDRESS, Volume) != 0)
00435   {
00436     ret =  AUDIO_ERROR;
00437   }
00438 
00439   /* Return AUDIO_OK when all operations are correctly done */
00440   return ret;
00441 }
00442 
00443 /**
00444   * @brief  Enables or disables the MUTE mode by software
00445   * @param  Cmd: Could be AUDIO_MUTE_ON to mute sound or AUDIO_MUTE_OFF to
00446   *         unmute the codec and restore previous volume level.
00447   * @retval AUDIO_OK if correct communication, else wrong communication
00448   */
00449 uint8_t BSP_AUDIO_OUT_SetMute(uint32_t Cmd)
00450 {
00451   uint8_t ret = AUDIO_OK;
00452 
00453   /* Call the Codec Mute function */
00454   if(audio_drv->SetMute(AUDIO_I2C_ADDRESS, Cmd) != 0)
00455   {
00456     ret = AUDIO_ERROR;
00457   }
00458 
00459   /* Return AUDIO_OK when all operations are correctly done */
00460   return ret;
00461 }
00462 
00463 /**
00464   * @brief  Switch dynamically (while audio file is being played) the output 
00465   *          target (speaker or headphone).
00466   * @param  Output: The audio output target: OUTPUT_DEVICE_SPEAKER,
00467   *         OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH
00468   * @retval AUDIO_OK if correct communication, else wrong communication
00469   */
00470 uint8_t BSP_AUDIO_OUT_SetOutputMode(uint8_t Output)
00471 {
00472   uint8_t ret = AUDIO_OK;
00473 
00474   /* Call the Codec output device function */
00475   if(audio_drv->SetOutputMode(AUDIO_I2C_ADDRESS, Output) != 0)
00476   {
00477     ret = AUDIO_ERROR;
00478   }
00479 
00480   /* Return AUDIO_OK when all operations are correctly done */
00481   return ret;
00482 }
00483 
00484 /**
00485   * @brief  Updates the audio frequency.
00486   * @param  AudioFreq: Audio frequency used to play the audio stream.
00487   * @note   This API should be called after the BSP_AUDIO_OUT_Init() to adjust the
00488   *         audio frequency.
00489   */
00490 void BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq)
00491 { 
00492   /* PLL clock is set depending by the AudioFreq (44.1khz vs 48khz groups) */ 
00493   BSP_AUDIO_OUT_ClockConfig(&haudio_out_sai, AudioFreq, NULL);
00494 
00495   /* Disable SAI peripheral to allow access to SAI internal registers */
00496   __HAL_SAI_DISABLE(&haudio_out_sai);
00497 
00498   /* Update the SAI audio frequency configuration */
00499   haudio_out_sai.Init.AudioFrequency = AudioFreq;
00500   HAL_SAI_Init(&haudio_out_sai);
00501 
00502   /* Enable SAI peripheral to generate MCLK */
00503   __HAL_SAI_ENABLE(&haudio_out_sai);
00504 }
00505 
00506 /**
00507   * @brief  Changes the Audio Out Configuration.
00508   * @param  AudioOutOption: specifies the audio out new configuration
00509   *         This parameter can be any value of @ref BSP_Audio_Out_Option
00510   * @note   This API should be called after the BSP_AUDIO_OUT_Init() to adjust the
00511   *         audio out configuration.
00512   */
00513 void BSP_AUDIO_OUT_ChangeAudioConfig(uint32_t AudioOutOption)
00514 { 
00515   /********** Playback Buffer circular/normal mode **********/
00516   if(AudioOutOption & BSP_AUDIO_OUT_CIRCULARMODE)
00517   {
00518     /* Deinitialize the Stream to update DMA mode */
00519     HAL_DMA_DeInit(haudio_out_sai.hdmatx);
00520     
00521     /* Update the SAI audio Transfer DMA mode */
00522     haudio_out_sai.hdmatx->Init.Mode = DMA_CIRCULAR;
00523     
00524     /* Configure the DMA Stream with new Transfer DMA mode */
00525     HAL_DMA_Init(haudio_out_sai.hdmatx);      
00526   }
00527   else /* BSP_AUDIO_OUT_NORMALMODE */
00528   {
00529     /* Deinitialize the Stream to update DMA mode */
00530     HAL_DMA_DeInit(haudio_out_sai.hdmatx);
00531     
00532     /* Update the SAI audio Transfer DMA mode */
00533     haudio_out_sai.hdmatx->Init.Mode = DMA_NORMAL;
00534     
00535     /* Configure the DMA Stream with new Transfer DMA mode */
00536     HAL_DMA_Init(haudio_out_sai.hdmatx);      
00537   }
00538   
00539   /********** Playback Buffer stereo/mono mode **********/
00540   if(AudioOutOption & BSP_AUDIO_OUT_STEREOMODE)
00541   {
00542     /* Disable SAI peripheral to allow access to SAI internal registers */
00543     __HAL_SAI_DISABLE(&haudio_out_sai);
00544     
00545     /* Update the SAI audio frame slot configuration */
00546     haudio_out_sai.Init.MonoStereoMode = SAI_STEREOMODE;
00547     HAL_SAI_Init(&haudio_out_sai);
00548     
00549     /* Enable SAI peripheral to generate MCLK */
00550     __HAL_SAI_ENABLE(&haudio_out_sai);
00551   }
00552   else /* BSP_AUDIO_OUT_MONOMODE */
00553   {
00554     /* Disable SAI peripheral to allow access to SAI internal registers */
00555     __HAL_SAI_DISABLE(&haudio_out_sai);
00556     
00557     /* Update the SAI audio frame slot configuration */
00558     haudio_out_sai.Init.MonoStereoMode = SAI_MONOMODE;
00559     HAL_SAI_Init(&haudio_out_sai);
00560     
00561     /* Enable SAI peripheral to generate MCLK */
00562     __HAL_SAI_ENABLE(&haudio_out_sai);
00563   }
00564 }
00565 
00566 /**
00567   * @brief  Updates the Audio frame slot configuration.
00568   * @param  AudioFrameSlot: specifies the audio Frame slot
00569   *         This parameter can be any value of @ref CODEC_AudioFrame_SLOT_TDMMode
00570   * @note   This API should be called after the BSP_AUDIO_OUT_Init() to adjust the
00571   *         audio frame slot.
00572   */
00573 void BSP_AUDIO_OUT_SetAudioFrameSlot(uint32_t AudioFrameSlot)
00574 {
00575   /* Disable SAI peripheral to allow access to SAI internal registers */
00576   __HAL_SAI_DISABLE(&haudio_out_sai);
00577 
00578   /* Update the SAI audio frame slot configuration */
00579   haudio_out_sai.SlotInit.SlotActive = AudioFrameSlot;
00580   HAL_SAI_Init(&haudio_out_sai);
00581 
00582   /* Enable SAI peripheral to generate MCLK */
00583   __HAL_SAI_ENABLE(&haudio_out_sai);
00584 }
00585 
00586 /**
00587   * @brief  Deinit the audio peripherals.
00588   */
00589 void BSP_AUDIO_OUT_DeInit(void)
00590 {
00591   SAIx_DeInit();
00592   /* DeInit the SAI MSP : this __weak function can be rewritten by the applic */
00593   BSP_AUDIO_OUT_MspDeInit(&haudio_out_sai, NULL);
00594  
00595   /* Reset the audio output context */
00596   memset(&audio_drv, 0, sizeof(audio_drv));
00597 }
00598 
00599 /**
00600   * @brief  Tx Transfer completed callbacks.
00601   * @param  hsai: SAI handle
00602   */
00603 void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
00604 {
00605   /* Manage the remaining file size and new address offset: This function
00606      should be coded by user (its prototype is already declared in stm32469i_discovery_audio.h) */
00607   BSP_AUDIO_OUT_TransferComplete_CallBack();
00608 }
00609 
00610 /**
00611   * @brief  Tx Half Transfer completed callbacks.
00612   * @param  hsai: SAI handle
00613   */
00614 void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
00615 {
00616   /* Manage the remaining file size and new address offset: This function
00617      should be coded by user (its prototype is already declared in stm32469i_discovery_audio.h) */
00618   BSP_AUDIO_OUT_HalfTransfer_CallBack();
00619 }
00620 
00621 /**
00622   * @brief  SAI error callbacks.
00623   * @param  hsai: SAI handle
00624   */
00625 void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai)
00626 {
00627   BSP_AUDIO_OUT_Error_CallBack();
00628 }
00629 
00630 /**
00631   * @brief  Manages the DMA full Transfer complete event.
00632   */
00633 __weak void BSP_AUDIO_OUT_TransferComplete_CallBack(void)
00634 {
00635 }
00636 
00637 /**
00638   * @brief  Manages the DMA Half Transfer complete event.
00639   */
00640 __weak void BSP_AUDIO_OUT_HalfTransfer_CallBack(void)
00641 {
00642 }
00643 
00644 /**
00645   * @brief  Manages the DMA FIFO error event.
00646   */
00647 __weak void BSP_AUDIO_OUT_Error_CallBack(void)
00648 {
00649 }
00650 
00651 /**
00652   * @brief  Initializes BSP_AUDIO_OUT MSP.
00653   * @param  hsai: SAI handle
00654   * @param  Params : pointer on additional configuration parameters, can be NULL.
00655   */
00656 __weak void BSP_AUDIO_OUT_MspInit(SAI_HandleTypeDef *hsai, void *Params)
00657 {
00658   static DMA_HandleTypeDef hdma_sai_tx;
00659   GPIO_InitTypeDef  gpio_init_structure;
00660 
00661   /* Put CS43L2 codec reset high -----------------------------------*/
00662   AUDIO_RESET_ENABLE();
00663   gpio_init_structure.Pin =  AUDIO_RESET_PIN;
00664   gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP;
00665   gpio_init_structure.Pull = GPIO_NOPULL;
00666   gpio_init_structure.Speed = GPIO_SPEED_HIGH;
00667   HAL_GPIO_Init(AUDIO_RESET_GPIO_PORT, &gpio_init_structure);
00668   HAL_GPIO_WritePin(AUDIO_RESET_GPIO_PORT, AUDIO_RESET_PIN, GPIO_PIN_SET);
00669 
00670   /* Enable SAI clock */
00671   AUDIO_SAIx_CLK_ENABLE();
00672 
00673   /* Enable GPIO clock */
00674   AUDIO_SAIx_MCLK_ENABLE();
00675   AUDIO_SAIx_SCK_SD_FS_ENABLE();
00676 
00677   /* CODEC_SAI pins configuration: MCK pin -----------------------------------*/
00678   gpio_init_structure.Pin =  AUDIO_SAIx_MCK_PIN;
00679   gpio_init_structure.Mode = GPIO_MODE_AF_PP;
00680   gpio_init_structure.Pull = GPIO_NOPULL;
00681   gpio_init_structure.Speed = GPIO_SPEED_HIGH;
00682   gpio_init_structure.Alternate = AUDIO_SAIx_MCLK_SCK_SD_FS_AF;
00683   HAL_GPIO_Init(AUDIO_SAIx_MCLK_GPIO_PORT, &gpio_init_structure);
00684 
00685   /* CODEC_SAI pins configuration: FS, SCK, MCK and SD pins ------------------*/
00686   gpio_init_structure.Pin = AUDIO_SAIx_FS_PIN | AUDIO_SAIx_SCK_PIN | AUDIO_SAIx_SD_PIN;
00687   gpio_init_structure.Mode = GPIO_MODE_AF_PP;
00688   gpio_init_structure.Pull = GPIO_NOPULL;
00689   gpio_init_structure.Speed = GPIO_SPEED_HIGH;
00690   gpio_init_structure.Alternate = AUDIO_SAIx_MCLK_SCK_SD_FS_AF;
00691   HAL_GPIO_Init(AUDIO_SAIx_SCK_SD_FS_GPIO_PORT, &gpio_init_structure);
00692 
00693   /* Enable the DMA clock */
00694   AUDIO_SAIx_DMAx_CLK_ENABLE();
00695 
00696   if(hsai->Instance == AUDIO_SAIx)
00697   {
00698     /* Configure the hdma_saiTx handle parameters */
00699     hdma_sai_tx.Init.Channel             = AUDIO_SAIx_DMAx_CHANNEL;
00700     hdma_sai_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
00701     hdma_sai_tx.Init.PeriphInc           = DMA_PINC_DISABLE;
00702     hdma_sai_tx.Init.MemInc              = DMA_MINC_ENABLE;
00703     hdma_sai_tx.Init.PeriphDataAlignment = AUDIO_SAIx_DMAx_PERIPH_DATA_SIZE;
00704     hdma_sai_tx.Init.MemDataAlignment    = AUDIO_SAIx_DMAx_MEM_DATA_SIZE;
00705     hdma_sai_tx.Init.Mode                = DMA_CIRCULAR;
00706     hdma_sai_tx.Init.Priority            = DMA_PRIORITY_HIGH;
00707     hdma_sai_tx.Init.FIFOMode            = DMA_FIFOMODE_ENABLE;
00708     hdma_sai_tx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
00709     hdma_sai_tx.Init.MemBurst            = DMA_MBURST_SINGLE;
00710     hdma_sai_tx.Init.PeriphBurst         = DMA_PBURST_SINGLE;
00711 
00712     hdma_sai_tx.Instance = AUDIO_SAIx_DMAx_STREAM;
00713 
00714     /* Associate the DMA handle */
00715     __HAL_LINKDMA(hsai, hdmatx, hdma_sai_tx);
00716 
00717     /* Deinitialize the Stream for new transfer */
00718     HAL_DMA_DeInit(&hdma_sai_tx);
00719 
00720     /* Configure the DMA Stream */
00721     HAL_DMA_Init(&hdma_sai_tx);
00722   }
00723 
00724   /* SAI DMA IRQ Channel configuration */
00725   HAL_NVIC_SetPriority(AUDIO_SAIx_DMAx_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0);
00726   HAL_NVIC_EnableIRQ(AUDIO_SAIx_DMAx_IRQ);
00727 
00728 }
00729 /**
00730   * @brief  Deinitializes BSP_AUDIO_OUT MSP.
00731   * @param  hsai: SAI handle
00732   * @param  Params : pointer on additional configuration parameters, can be NULL.
00733   */
00734 __weak void BSP_AUDIO_OUT_MspDeInit(SAI_HandleTypeDef *hsai, void *Params)
00735 {
00736   GPIO_InitTypeDef  gpio_init_structure;
00737 
00738   /* SAI DMA IRQ Channel deactivation */
00739   HAL_NVIC_DisableIRQ(AUDIO_SAIx_DMAx_IRQ);
00740 
00741   if(hsai->Instance == AUDIO_SAIx)
00742   {
00743     /* Deinitialize the DMA stream */
00744     HAL_DMA_DeInit(hsai->hdmatx);
00745   }
00746 
00747   /* Disable SAI peripheral */
00748   __HAL_SAI_DISABLE(hsai);  
00749 
00750   /* Put CS43L2 codec reset low -----------------------------------*/
00751   HAL_GPIO_WritePin(AUDIO_RESET_GPIO_PORT, AUDIO_RESET_PIN, GPIO_PIN_RESET);
00752 
00753   /* Deactives CODEC_SAI pins FS, SCK, MCK and SD by putting them in input mode */
00754   gpio_init_structure.Pin = AUDIO_SAIx_MCK_PIN;
00755   HAL_GPIO_DeInit(AUDIO_SAIx_MCLK_GPIO_PORT, gpio_init_structure.Pin);
00756 
00757   gpio_init_structure.Pin = AUDIO_SAIx_FS_PIN | AUDIO_SAIx_SCK_PIN | AUDIO_SAIx_SD_PIN;
00758   HAL_GPIO_DeInit(AUDIO_SAIx_SCK_SD_FS_GPIO_PORT, gpio_init_structure.Pin);
00759  
00760   gpio_init_structure.Pin = AUDIO_RESET_PIN;
00761   HAL_GPIO_DeInit(AUDIO_RESET_GPIO_PORT, gpio_init_structure.Pin);
00762 
00763 
00764   /* Disable SAI clock */
00765   AUDIO_SAIx_CLK_DISABLE();
00766 
00767   
00768   /* GPIO pins clock and DMA clock can be shut down in the applic 
00769      by surcgarging this __weak function */ 
00770 }
00771 
00772 /**
00773   * @brief  Clock Config.
00774   * @param  hsai: might be required to set audio peripheral predivider if any.
00775   * @param  AudioFreq: Audio frequency used to play the audio stream.
00776   * @note   This API is called by BSP_AUDIO_OUT_Init() and BSP_AUDIO_OUT_SetFrequency()
00777   *         Being __weak it can be overwritten by the application     
00778   * @param  Params : pointer on additional configuration parameters, can be NULL.
00779   */
00780 __weak void BSP_AUDIO_OUT_ClockConfig(SAI_HandleTypeDef *hsai, uint32_t AudioFreq, void *Params)
00781 { 
00782   RCC_PeriphCLKInitTypeDef rcc_ex_clk_init_struct;
00783 
00784   HAL_RCCEx_GetPeriphCLKConfig(&rcc_ex_clk_init_struct);
00785   
00786   /* Set the PLL configuration according to the audio frequency */
00787   if((AudioFreq == AUDIO_FREQUENCY_11K) || (AudioFreq == AUDIO_FREQUENCY_22K) || (AudioFreq == AUDIO_FREQUENCY_44K))
00788   {
00789     /* Configure PLLI2S prescalers */
00790     /* PLLI2S_VCO: VCO_429M
00791     I2S_CLK(first level) = PLLI2S_VCO/PLLI2SQ = 429/2 = 214.5 Mhz
00792     I2S_CLK_x = I2S_CLK(first level)/PLLI2SDIVQ = 214.5/19 = 11.289 Mhz */
00793     rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI_PLLI2S;
00794     rcc_ex_clk_init_struct.PLLI2S.PLLI2SN = 429;
00795     rcc_ex_clk_init_struct.PLLI2S.PLLI2SQ = 2;
00796     rcc_ex_clk_init_struct.PLLI2SDivQ = 19;
00797     
00798     HAL_RCCEx_PeriphCLKConfig(&rcc_ex_clk_init_struct);
00799     
00800   }
00801   else /* AUDIO_FREQUENCY_8K, AUDIO_FREQUENCY_16K, AUDIO_FREQUENCY_48K), AUDIO_FREQUENCY_96K */
00802   {
00803     /* SAI clock config 
00804     PLLSAI_VCO: VCO_344M 
00805     I2S_CLK(first level) = PLLI2S_VCO/PLLI2SQ = 344/7 = 49.142 Mhz 
00806     I2S_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ = 49.142/1 = 49.142 Mhz */  
00807     rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI_PLLI2S;
00808     rcc_ex_clk_init_struct.PLLI2S.PLLI2SN = 344; 
00809     rcc_ex_clk_init_struct.PLLI2S.PLLI2SQ = 7; 
00810     rcc_ex_clk_init_struct.PLLI2SDivQ = 1;       
00811     
00812     HAL_RCCEx_PeriphCLKConfig(&rcc_ex_clk_init_struct);
00813   }
00814 }
00815 
00816 /*******************************************************************************
00817                             Static Functions
00818 *******************************************************************************/
00819 /**
00820   * @brief  Initializes the Audio Codec audio interface (SAI).
00821   * @param  AudioFreq: Audio frequency to be configured for the SAI peripheral.
00822   * @note   The default SlotActive configuration is set to CODEC_AUDIOFRAME_SLOT_0123
00823   *         and user can update this configuration using
00824   */
00825 static uint8_t SAIx_Init(uint32_t AudioFreq)
00826 {
00827   uint8_t ret = AUDIO_OK;
00828 
00829   /* Initialize the haudio_out_sai Instance parameter */
00830   haudio_out_sai.Instance = AUDIO_SAIx;
00831 
00832   /* Disable SAI peripheral to allow access to SAI internal registers */
00833   __HAL_SAI_DISABLE(&haudio_out_sai);
00834 
00835   /* Configure SAI_Block_x
00836   LSBFirst: Disabled
00837   DataSize: 16 */
00838   haudio_out_sai.Init.AudioFrequency = AudioFreq;
00839   haudio_out_sai.Init.ClockSource = SAI_CLKSOURCE_PLLI2S;
00840   haudio_out_sai.Init.AudioMode = SAI_MODEMASTER_TX;
00841   haudio_out_sai.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
00842   haudio_out_sai.Init.Protocol = SAI_FREE_PROTOCOL;
00843   haudio_out_sai.Init.DataSize = SAI_DATASIZE_16;
00844   haudio_out_sai.Init.FirstBit = SAI_FIRSTBIT_MSB;
00845   haudio_out_sai.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
00846   haudio_out_sai.Init.Synchro = SAI_ASYNCHRONOUS;
00847   haudio_out_sai.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
00848   haudio_out_sai.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
00849 /*
00850   haudio_out_sai.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_MCKDIV;
00851   haudio_out_sai.Init.SynchroExt     = SAI_SYNCEXT_DISABLE;
00852   haudio_out_sai.Init.Mckdiv         = SAIClockDivider(AudioFreq);
00853   haudio_out_sai.Init.MonoStereoMode = SAI_STEREOMODE;
00854   haudio_out_sai.Init.CompandingMode = SAI_NOCOMPANDING;
00855   haudio_out_sai.Init.TriState       = SAI_OUTPUT_NOTRELEASED;
00856 */
00857 
00858   /* Configure SAI_Block_x Frame
00859   Frame Length: 64
00860   Frame active Length: 32
00861   FS Definition: Start frame + Channel Side identification
00862   FS Polarity: FS active Low
00863   FS Offset: FS asserted one bit before the first bit of slot 0 */
00864   haudio_out_sai.FrameInit.FrameLength = 64;
00865   haudio_out_sai.FrameInit.ActiveFrameLength = 32;
00866   haudio_out_sai.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
00867   haudio_out_sai.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
00868   haudio_out_sai.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
00869 
00870   /* Configure SAI Block_x Slot
00871   Slot First Bit Offset: 0
00872   Slot Size  : 16
00873   Slot Number: 4
00874   Slot Active: All slot actives */
00875   haudio_out_sai.SlotInit.FirstBitOffset = 0;
00876   haudio_out_sai.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
00877   haudio_out_sai.SlotInit.SlotNumber = 4;
00878   haudio_out_sai.SlotInit.SlotActive = CODEC_AUDIOFRAME_SLOT_0123;
00879 
00880   /* Initializes the SAI peripheral*/
00881   if (HAL_SAI_Init(&haudio_out_sai) != HAL_OK)
00882   {
00883     ret = AUDIO_ERROR;
00884   }
00885 
00886   /* Enable SAI peripheral to generate MCLK */
00887   __HAL_SAI_ENABLE(&haudio_out_sai);
00888 
00889   return ret;
00890 
00891 }
00892 
00893 /**
00894   * @brief  Deinitializes the Audio Codec audio interface (SAI).
00895   */
00896 static void SAIx_DeInit(void)
00897 {
00898   /* Initialize the hAudioOutSai Instance parameter */
00899   haudio_out_sai.Instance = AUDIO_SAIx;
00900 
00901   /* Disable SAI peripheral */
00902   __HAL_SAI_DISABLE(&haudio_out_sai);
00903 
00904   HAL_SAI_DeInit(&haudio_out_sai);
00905 }
00906 
00907 /**
00908   * @}
00909   */
00910 
00911 /** @defgroup STM32469I-Discovery_AUDIO_in_Private_Functions STM32469I Discovery AUDIO IN Private functions
00912   * @{
00913   */
00914 
00915 /**
00916   * @brief  Initializes wave recording.
00917   * @note   This function assumes that the I2S input clock (through PLL_R in
00918   *         Devices RevA/Z and through dedicated PLLI2S_R in Devices RevB/Y)
00919   *         is already configured and ready to be used.
00920   * @param  AudioFreq: Audio frequency to be configured for the I2S peripheral.
00921   * @param  BitRes: Audio frequency to be configured for the I2S peripheral.
00922   * @param  ChnlNbr: Audio frequency to be configured for the I2S peripheral.
00923   * @retval AUDIO_OK if correct communication, else wrong communication
00924   */
00925 uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
00926 {
00927   /* DeInit the I2S */
00928   I2Sx_DeInit();
00929 
00930   /* Configure PLL clock */ 
00931   BSP_AUDIO_IN_ClockConfig(&haudio_in_i2s, NULL);
00932 
00933   /* Configure the PDM library */
00934   PDMDecoder_Init(AudioFreq, ChnlNbr);
00935  
00936   /* Configure the I2S peripheral */
00937   haudio_in_i2s.Instance = AUDIO_I2Sx;
00938   if(HAL_I2S_GetState(&haudio_in_i2s) == HAL_I2S_STATE_RESET)
00939   { 
00940     /* Initialize the I2S Msp: this __weak function can be rewritten by the application */
00941     BSP_AUDIO_IN_MspInit(&haudio_in_i2s, NULL);
00942   }
00943 
00944   I2Sx_Init(AudioFreq);
00945 
00946   /* Return AUDIO_OK when all operations are correctly done */
00947   return AUDIO_OK;
00948 }
00949 
00950 /**
00951   * @brief  Starts audio recording.
00952   * @param  pbuf: Main buffer pointer for the recorded data storing
00953   * @param  size: Current size of the recorded buffer
00954   * @retval AUDIO_OK if correct communication, else wrong communication
00955   */
00956 uint8_t BSP_AUDIO_IN_Record(uint16_t* pbuf, uint32_t size)
00957 {
00958   uint32_t ret = AUDIO_ERROR;
00959 
00960   /* Start the process receive DMA */
00961   HAL_I2S_Receive_DMA(&haudio_in_i2s, pbuf, size);
00962 
00963   /* Return AUDIO_OK when all operations are correctly done */
00964   ret = AUDIO_OK;
00965 
00966   return ret;
00967 }
00968 
00969 /**
00970   * @brief  Stops audio recording.
00971   * @retval AUDIO_OK if correct communication, else wrong communication
00972   */
00973 uint8_t BSP_AUDIO_IN_Stop(void)
00974 {
00975   uint32_t ret = AUDIO_ERROR;
00976 
00977   /* Call the Media layer pause function */
00978   HAL_I2S_DMAPause(&haudio_in_i2s);
00979 
00980   /* TIMx Peripheral clock disable */
00981   AUDIO_TIMx_CLK_DISABLE();
00982 
00983   /* Return AUDIO_OK when all operations are correctly done */
00984   ret = AUDIO_OK;
00985 
00986   return ret;
00987 }
00988 
00989 /**
00990   * @brief  Pauses the audio file stream.
00991   * @retval AUDIO_OK if correct communication, else wrong communication
00992   */
00993 uint8_t BSP_AUDIO_IN_Pause(void)
00994 {
00995   /* Call the Media layer pause function */
00996   HAL_I2S_DMAPause(&haudio_in_i2s);
00997 
00998   /* Return AUDIO_OK when all operations are correctly done */
00999   return AUDIO_OK;
01000 }
01001 
01002 /**
01003   * @brief  Resumes the audio file stream.
01004   * @retval AUDIO_OK if correct communication, else wrong communication
01005   */
01006 uint8_t BSP_AUDIO_IN_Resume(void)
01007 {
01008   /* Call the Media layer pause/resume function */
01009   HAL_I2S_DMAResume(&haudio_in_i2s);
01010 
01011   /* Return AUDIO_OK when all operations are correctly done */
01012   return AUDIO_OK;
01013 }
01014 
01015 /**
01016   * @brief  Controls the audio in volume level.
01017   * @param  Volume: Volume level to be set in percentage from 0% to 100% (0 for
01018   *         Mute and 100 for Max volume level).
01019   * @retval AUDIO_OK if correct communication, else wrong communication
01020   */
01021 uint8_t BSP_AUDIO_IN_SetVolume(uint8_t Volume)
01022 {
01023   /* Set the Global variable AudioInVolume  */
01024   AudioInVolume = Volume;
01025 
01026   /* Return AUDIO_OK when all operations are correctly done */
01027   return AUDIO_OK;
01028 }
01029 
01030 /**
01031   * @brief  Deinit the audio IN peripherals.
01032   */
01033 void BSP_AUDIO_IN_DeInit(void)
01034 {
01035   I2Sx_DeInit();
01036     /* DeInit the I2S MSP : this __weak function can be rewritten by the applic */
01037   BSP_AUDIO_IN_MspDeInit(&haudio_in_i2s, NULL);
01038   TIMx_DeInit();
01039 }
01040 
01041 /**
01042   * @brief  Converts audio format from PDM to PCM.
01043   * @param  PDMBuf: Pointer to data PDM buffer
01044   * @param  PCMBuf: Pointer to data PCM buffer
01045   * @retval AUDIO_OK if correct communication, else wrong communication
01046   */
01047 uint8_t BSP_AUDIO_IN_PDMToPCM(uint16_t* PDMBuf, uint16_t* PCMBuf)
01048 {
01049   uint8_t app_pdm[INTERNAL_BUFF_SIZE*2];
01050   uint8_t byte1 = 0, byte2 = 0;
01051   uint32_t index = 0;
01052 
01053   /* PDM Demux */
01054   for(index = 0; index<INTERNAL_BUFF_SIZE/2; index++)
01055   {
01056     byte2 = (PDMBuf[index] >> 8)& 0xFF;
01057     byte1 = (PDMBuf[index] & 0xFF);
01058     app_pdm[(index*2)+1] = Channel_Demux[byte1 & CHANNEL_DEMUX_MASK] | Channel_Demux[byte2 & CHANNEL_DEMUX_MASK] << 4;
01059     app_pdm[(index*2)] = Channel_Demux[(byte1 >> 1) & CHANNEL_DEMUX_MASK] | Channel_Demux[(byte2 >> 1) & CHANNEL_DEMUX_MASK] << 4;
01060   }
01061 
01062   for(index = 0; index < DEFAULT_AUDIO_IN_CHANNEL_NBR; index++)
01063   {
01064     /* PDM to PCM filter */
01065     PDM_Filter_64_LSB((uint8_t*)&app_pdm[index], (uint16_t*)&(PCMBuf[index]), AudioInVolume , (PDMFilter_InitStruct *)&Filter[index]);
01066   }
01067 
01068   /* Return AUDIO_OK when all operations are correctly done */
01069   return AUDIO_OK;
01070 }
01071 
01072  /**
01073   * @brief  Rx Transfer completed callbacks.
01074   * @param  hi2s: I2S handle
01075   */
01076 void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
01077 {
01078   /* Call the record update function to get the next buffer to fill and its size (size is ignored) */
01079   BSP_AUDIO_IN_TransferComplete_CallBack();
01080 }
01081 
01082 /**
01083   * @brief  Rx Half Transfer completed callbacks.
01084   * @param  hi2s: I2S handle
01085   */
01086 void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
01087 {
01088   /* Manage the remaining file size and new address offset: This function
01089      should be coded by user (its prototype is already declared in stm32469i_discovery_audio.h) */
01090   BSP_AUDIO_IN_HalfTransfer_CallBack();
01091 }
01092 
01093 /**
01094   * @brief  I2S error callbacks.
01095   * @param  hi2s: I2S handle
01096   */
01097 void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s)
01098 {
01099   /* Manage the error generated on DMA FIFO: This function
01100      should be coded by user (its prototype is already declared in stm32469i_discovery_audio.h) */
01101   BSP_AUDIO_IN_Error_Callback();
01102 }
01103 
01104 /**
01105   * @brief  Clock Config.
01106   * @param  hi2s: I2S handle
01107   * @param  Params : pointer on additional configuration parameters, can be NULL.   
01108   * @note   This API is called by BSP_AUDIO_IN_Init()
01109   *         Being __weak it can be overwritten by the application
01110   */
01111 __weak void BSP_AUDIO_IN_ClockConfig(I2S_HandleTypeDef *hi2s, void *Params)
01112 {
01113   RCC_PeriphCLKInitTypeDef RCC_ExCLKInitStruct;
01114   
01115   HAL_RCCEx_GetPeriphCLKConfig(&RCC_ExCLKInitStruct);
01116   RCC_ExCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S;
01117   RCC_ExCLKInitStruct.PLLI2S.PLLI2SN = 384;
01118   RCC_ExCLKInitStruct.PLLI2S.PLLI2SR = 2;
01119   HAL_RCCEx_PeriphCLKConfig(&RCC_ExCLKInitStruct); 
01120 }
01121 
01122 /**
01123   * @brief  User callback when record buffer is filled.
01124   */
01125 __weak void BSP_AUDIO_IN_TransferComplete_CallBack(void)
01126 {
01127   /* This function should be implemented by the user application.
01128      It is called into this driver when the current buffer is filled
01129      to prepare the next buffer pointer and its size. */
01130 }
01131 
01132 /**
01133   * @brief  Manages the DMA Half Transfer complete event.
01134   */
01135 __weak void BSP_AUDIO_IN_HalfTransfer_CallBack(void)
01136 {
01137   /* This function should be implemented by the user application.
01138      It is called into this driver when the current buffer is filled
01139      to prepare the next buffer pointer and its size. */
01140 }
01141 
01142 /**
01143   * @brief  Audio IN Error callback function.
01144   */
01145 __weak void BSP_AUDIO_IN_Error_Callback(void)
01146 {
01147   /* This function is called when an Interrupt due to transfer error on or peripheral
01148      error occurs. */
01149 }
01150 
01151 /**
01152   * @brief  BSP AUDIO IN MSP Init.
01153   * @param  hi2s: I2S handle
01154   * @param  Params : pointer on additional configuration parameters, can be NULL.
01155   */
01156 __weak void BSP_AUDIO_IN_MspInit(I2S_HandleTypeDef *hi2s, void *Params)
01157 {
01158   static DMA_HandleTypeDef hdma_i2s_rx;
01159   GPIO_InitTypeDef  gpio_init_structure;
01160 
01161   /* Configure the Timer which clocks the MEMS */
01162   /* Moved inside MSP to allow applic to redefine the TIMx_MspInit */
01163   TIMx_Init();
01164   
01165   /* Enable I2S clock */
01166   AUDIO_I2Sx_CLK_ENABLE();
01167 
01168   /* Enable SCK and SD GPIO clock */
01169   AUDIO_I2Sx_SD_GPIO_CLK_ENABLE();
01170   AUDIO_I2Sx_SCK_GPIO_CLK_ENABLE();
01171   /* CODEC_I2S pins configuration: SCK and SD pins */
01172   gpio_init_structure.Pin = AUDIO_I2Sx_SCK_PIN;
01173   gpio_init_structure.Mode = GPIO_MODE_AF_PP;
01174   gpio_init_structure.Pull = GPIO_NOPULL;
01175   gpio_init_structure.Speed = GPIO_SPEED_FAST;
01176   gpio_init_structure.Alternate = AUDIO_I2Sx_SCK_AF;
01177   HAL_GPIO_Init(AUDIO_I2Sx_SCK_GPIO_PORT, &gpio_init_structure);
01178 
01179   gpio_init_structure.Pin = AUDIO_I2Sx_SD_PIN;
01180   gpio_init_structure.Alternate = AUDIO_I2Sx_SD_AF;
01181   HAL_GPIO_Init(AUDIO_I2Sx_SD_GPIO_PORT, &gpio_init_structure);
01182 
01183   /* Enable PD12 (I2S3_CLK) connected to PB3 via jamper JP4 */
01184   /* on Eval this was provided by PC6 (initialized in TIMx section) */
01185 /*
01186   gpio_init_structure.Pin = GPIO_PIN_12;
01187   gpio_init_structure.Mode = GPIO_MODE_AF_PP;
01188   gpio_init_structure.Pull = GPIO_NOPULL;
01189   gpio_init_structure.Speed = GPIO_SPEED_FAST;
01190   gpio_init_structure.Alternate = AUDIO_I2Sx_SCK_AF;
01191   HAL_GPIO_Init(GPIOD, &gpio_init_structure); */
01192   
01193 
01194   /* Enable the DMA clock */
01195   AUDIO_I2Sx_DMAx_CLK_ENABLE();
01196 
01197   if(hi2s->Instance == AUDIO_I2Sx)
01198   {
01199     /* Configure the hdma_i2sRx handle parameters */
01200     hdma_i2s_rx.Init.Channel             = AUDIO_I2Sx_DMAx_CHANNEL;
01201     hdma_i2s_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;
01202     hdma_i2s_rx.Init.PeriphInc           = DMA_PINC_DISABLE;
01203     hdma_i2s_rx.Init.MemInc              = DMA_MINC_ENABLE;
01204     hdma_i2s_rx.Init.PeriphDataAlignment = AUDIO_I2Sx_DMAx_PERIPH_DATA_SIZE;
01205     hdma_i2s_rx.Init.MemDataAlignment    = AUDIO_I2Sx_DMAx_MEM_DATA_SIZE;
01206     hdma_i2s_rx.Init.Mode                = DMA_CIRCULAR;
01207     hdma_i2s_rx.Init.Priority            = DMA_PRIORITY_HIGH;
01208     hdma_i2s_rx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
01209     hdma_i2s_rx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
01210     hdma_i2s_rx.Init.MemBurst            = DMA_MBURST_SINGLE;
01211     hdma_i2s_rx.Init.PeriphBurst         = DMA_MBURST_SINGLE;
01212 
01213     hdma_i2s_rx.Instance = AUDIO_I2Sx_DMAx_STREAM;
01214 
01215     /* Associate the DMA handle */
01216     __HAL_LINKDMA(hi2s, hdmarx, hdma_i2s_rx);
01217 
01218     /* Deinitialize the Stream for new transfer */
01219     HAL_DMA_DeInit(&hdma_i2s_rx);
01220 
01221     /* Configure the DMA Stream */
01222     HAL_DMA_Init(&hdma_i2s_rx);
01223   }
01224 
01225   /* I2S DMA IRQ Channel configuration */
01226   HAL_NVIC_SetPriority(AUDIO_I2Sx_DMAx_IRQ, AUDIO_IN_IRQ_PREPRIO, 0);
01227   HAL_NVIC_EnableIRQ(AUDIO_I2Sx_DMAx_IRQ);
01228 }
01229 
01230 /**
01231   * @brief  DeInitializes BSP_AUDIO_IN MSP.
01232   * @param  hi2s: I2S handle
01233   * @param  Params : pointer on additional configuration parameters, can be NULL.
01234   */
01235 __weak void BSP_AUDIO_IN_MspDeInit(I2S_HandleTypeDef *hi2s, void *Params)
01236 {
01237   GPIO_InitTypeDef  gpio_init_structure;
01238 
01239   /* I2S DMA IRQ Channel deactivation */
01240   HAL_NVIC_DisableIRQ(AUDIO_I2Sx_DMAx_IRQ); 
01241   
01242   if(hi2s->Instance == AUDIO_I2Sx)
01243   {
01244     /* Deinitialize the Stream for new transfer */
01245     HAL_DMA_DeInit(hi2s->hdmarx);
01246   }
01247 
01248  /* Disable I2S block */
01249   __HAL_I2S_DISABLE(hi2s);
01250 
01251   /* Disable pins: SCK and SD pins */
01252   gpio_init_structure.Pin = AUDIO_I2Sx_SCK_PIN;
01253   HAL_GPIO_DeInit(AUDIO_I2Sx_SCK_GPIO_PORT, gpio_init_structure.Pin);
01254   gpio_init_structure.Pin = AUDIO_I2Sx_SD_PIN;
01255   HAL_GPIO_DeInit(AUDIO_I2Sx_SD_GPIO_PORT, gpio_init_structure.Pin); 
01256 
01257   /* Disable I2S clock */
01258   AUDIO_I2Sx_CLK_DISABLE();
01259 
01260   /* GPIO pins clock and DMA clock can be shut down in the applic 
01261      by surcgarging this __weak function */ 
01262 }
01263 
01264 /*******************************************************************************
01265                             Static Functions
01266 *******************************************************************************/
01267 
01268 /**
01269   * @brief  Initializes the PDM library.
01270   * @param  AudioFreq: Audio sampling frequency
01271   * @param  ChnlNbr: Number of audio channels (1: mono; 2: stereo)
01272   */
01273 static void PDMDecoder_Init(uint32_t AudioFreq, uint32_t ChnlNbr)
01274 {
01275   uint32_t i = 0;
01276 
01277   /* Enable CRC peripheral to unlock the PDM library */
01278   __HAL_RCC_CRC_CLK_ENABLE();
01279 
01280   for(i = 0; i < ChnlNbr; i++)
01281   {
01282     /* Filter LP & HP Init */
01283     Filter[i].LP_HZ = AudioFreq/2;
01284     Filter[i].HP_HZ = 10;
01285     Filter[i].Fs = AudioFreq;
01286     Filter[i].Out_MicChannels = ChnlNbr;
01287     Filter[i].In_MicChannels = ChnlNbr;
01288     PDM_Filter_Init((PDMFilter_InitStruct *)&Filter[i]);
01289   }
01290 }
01291 
01292 /**
01293   * @brief  Initializes the Audio Codec audio interface (I2S)
01294   * @note   This function assumes that the I2S input clock (through dedicated PLLI2S_R)
01295   *         is already configured and ready to be used.
01296   * @param  AudioFreq: Audio frequency to be configured for the I2S peripheral.
01297   */
01298 static void I2Sx_Init(uint32_t AudioFreq)
01299 {
01300   /* Initialize the haudio_in_i2s Instance parameter */
01301   haudio_in_i2s.Instance = AUDIO_I2Sx;
01302 
01303  /* Disable I2S block */
01304   __HAL_I2S_DISABLE(&haudio_in_i2s);
01305 
01306   /* I2S2 peripheral configuration */
01307   haudio_in_i2s.Init.AudioFreq = 4 * AudioFreq;
01308   haudio_in_i2s.Init.ClockSource = I2S_CLOCK_PLL;
01309   haudio_in_i2s.Init.CPOL = I2S_CPOL_LOW;
01310   haudio_in_i2s.Init.DataFormat = I2S_DATAFORMAT_16B;
01311   haudio_in_i2s.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE;
01312   haudio_in_i2s.Init.Mode = I2S_MODE_MASTER_RX;
01313   haudio_in_i2s.Init.Standard = I2S_STANDARD_LSB;
01314   
01315   /* Init the I2S */
01316   HAL_I2S_Init(&haudio_in_i2s); 
01317 
01318  /* Disable I2S block */
01319   __HAL_I2S_ENABLE(&haudio_in_i2s);
01320 
01321 }
01322 
01323 /**
01324   * @brief  Deinitializes the Audio Codec audio interface (I2S).
01325   */
01326 static void I2Sx_DeInit(void)
01327 {
01328   /* Initialize the hAudioInI2s Instance parameter */
01329   haudio_in_i2s.Instance = AUDIO_I2Sx;
01330 
01331  /* Disable I2S block */
01332   __HAL_I2S_DISABLE(&haudio_in_i2s);
01333 
01334   /* DeInit the I2S */
01335   HAL_I2S_DeInit(&haudio_in_i2s); 
01336 }
01337 
01338 
01339 /**
01340   * @brief  Initializes the TIM INput Capture MSP.
01341   * @param  htim: TIM handle
01342   */
01343 static void TIMx_IC_MspInit(TIM_HandleTypeDef *htim)
01344 {
01345   GPIO_InitTypeDef   gpio_init_structure;
01346 
01347   /* Enable peripherals and GPIO Clocks --------------------------------------*/
01348   /* TIMx Peripheral clock enable */
01349   AUDIO_TIMx_CLK_ENABLE();
01350 
01351   /* Enable GPIO Channels Clock */
01352   AUDIO_TIMx_GPIO_CLK_ENABLE();
01353 
01354   /* Configure I/Os ----------------------------------------------------------*/
01355   /* Common configuration for all channels */
01356   gpio_init_structure.Mode = GPIO_MODE_AF_PP;
01357   gpio_init_structure.Pull = GPIO_NOPULL;
01358   gpio_init_structure.Speed = GPIO_SPEED_HIGH;
01359   gpio_init_structure.Alternate = AUDIO_TIMx_AF;
01360 
01361   /* Configure TIM input channel */
01362   gpio_init_structure.Pin = AUDIO_TIMx_IN_GPIO_PIN;
01363   HAL_GPIO_Init(AUDIO_TIMx_GPIO_PORT, &gpio_init_structure);
01364 
01365   /* Configure TIM output channel */
01366   gpio_init_structure.Pin = AUDIO_TIMx_OUT_GPIO_PIN;
01367   HAL_GPIO_Init(AUDIO_TIMx_GPIO_PORT, &gpio_init_structure);
01368 }
01369 
01370 /**
01371   * @brief  Initializes the TIM INput Capture MSP.
01372   * @param  htim: TIM handle
01373   */
01374 static void TIMx_IC_MspDeInit(TIM_HandleTypeDef *htim)
01375 {
01376     /* Disable TIMx Peripheral clock  */
01377     AUDIO_TIMx_CLK_DISABLE();
01378 
01379     /* GPIO pins clock and DMA clock can be shut down in the applic 
01380        by surcgarging this __weak function */ 
01381 }
01382 
01383 /**
01384   * @brief  Configure TIM as a clock divider by 2.
01385   *         I2S_SCK is externally connected to TIMx input channel
01386   */
01387 static void TIMx_Init(void)
01388 {
01389   TIM_IC_InitTypeDef     s_ic_config;
01390   TIM_OC_InitTypeDef     s_oc_config;
01391   TIM_ClockConfigTypeDef s_clk_source_config;
01392   TIM_SlaveConfigTypeDef s_slave_config;
01393   
01394   /* Configure the TIM peripheral --------------------------------------------*/
01395   /* Set TIMx instance */
01396   haudio_tim.Instance = AUDIO_TIMx;
01397   /* Timer Input Capture Configuration Structure declaration */
01398    /* Initialize TIMx peripheral as follow:
01399        + Period = 0xFFFF
01400        + Prescaler = 0
01401        + ClockDivision = 0
01402        + Counter direction = Up
01403   */
01404   haudio_tim.Init.Period        = 1;
01405   haudio_tim.Init.Prescaler     = 0;
01406   haudio_tim.Init.ClockDivision = 0;
01407   haudio_tim.Init.CounterMode   = TIM_COUNTERMODE_UP;
01408 
01409   /* Initialize the TIMx peripheral with the structure above */
01410   TIMx_IC_MspInit(&haudio_tim);
01411   HAL_TIM_IC_Init(&haudio_tim);
01412 
01413   /* Configure the Input Capture channel -------------------------------------*/
01414   /* Configure the Input Capture of channel 2 */
01415   s_ic_config.ICPolarity  = TIM_ICPOLARITY_FALLING;
01416   s_ic_config.ICSelection = TIM_ICSELECTION_DIRECTTI;
01417   s_ic_config.ICPrescaler = TIM_ICPSC_DIV1;
01418   s_ic_config.ICFilter    = 0;
01419   HAL_TIM_IC_ConfigChannel(&haudio_tim, &s_ic_config, AUDIO_TIMx_IN_CHANNEL);
01420   
01421   /* Select external clock mode 1 */
01422   s_clk_source_config.ClockSource = TIM_CLOCKSOURCE_ETRMODE1;
01423   s_clk_source_config.ClockPolarity = TIM_CLOCKPOLARITY_NONINVERTED;
01424   s_clk_source_config.ClockPrescaler = TIM_CLOCKPRESCALER_DIV1;
01425   s_clk_source_config.ClockFilter = 0;   
01426   HAL_TIM_ConfigClockSource(&haudio_tim, &s_clk_source_config);
01427   
01428   /* Select Input Channel as input trigger */
01429   s_slave_config.InputTrigger = TIM_TS_TI1FP1;
01430   s_slave_config.SlaveMode = TIM_SLAVEMODE_EXTERNAL1;
01431   s_slave_config.TriggerPolarity = TIM_TRIGGERPOLARITY_NONINVERTED;
01432   s_slave_config.TriggerPrescaler = TIM_CLOCKPRESCALER_DIV1;
01433   s_slave_config.TriggerFilter = 0;
01434   HAL_TIM_SlaveConfigSynchronization(&haudio_tim, &s_slave_config);
01435   
01436   /* Output Compare PWM Mode configuration: Channel2 */
01437   s_oc_config.OCMode = TIM_OCMODE_PWM1;
01438   s_oc_config.OCIdleState = TIM_OCIDLESTATE_SET;
01439   s_oc_config.Pulse = 1;
01440   s_oc_config.OCPolarity = TIM_OCPOLARITY_HIGH;
01441   s_oc_config.OCNPolarity = TIM_OCNPOLARITY_HIGH;
01442   s_oc_config.OCFastMode = TIM_OCFAST_DISABLE;
01443   s_oc_config.OCNIdleState = TIM_OCNIDLESTATE_SET;
01444   
01445   /* Initialize the TIM3 Channel2 with the structure above */
01446   HAL_TIM_PWM_ConfigChannel(&haudio_tim, &s_oc_config, AUDIO_TIMx_OUT_CHANNEL);
01447 
01448   /* Start the TIM3 Channel2 */
01449   HAL_TIM_PWM_Start(&haudio_tim, AUDIO_TIMx_OUT_CHANNEL);
01450 
01451   /* Start the TIM3 Channel1 */
01452   HAL_TIM_IC_Start(&haudio_tim, AUDIO_TIMx_IN_CHANNEL);
01453 }
01454 
01455 /**
01456   * @brief  Configure TIM as a clock divider by 2.
01457   *         I2S_SCK is externally connected to TIMx input channel
01458   */
01459 static void TIMx_DeInit(void)
01460 {
01461   haudio_tim.Instance = AUDIO_TIMx;
01462   
01463   /* Stop the TIM3 Channel2 */
01464   HAL_TIM_PWM_Stop(&haudio_tim, AUDIO_TIMx_OUT_CHANNEL);
01465   /* Stop the TIM3 Channel1 */
01466   HAL_TIM_IC_Stop(&haudio_tim, AUDIO_TIMx_IN_CHANNEL);
01467 
01468   HAL_TIM_IC_DeInit(&haudio_tim);
01469   
01470   /* Initialize the TIMx peripheral with the structure above */
01471   TIMx_IC_MspDeInit(&haudio_tim);
01472 }
01473 
01474 /**
01475   * @}
01476   */ 
01477   
01478 /**
01479   * @}
01480   */
01481 
01482 /**
01483   * @}
01484   */
01485 
01486 /**
01487   * @}
01488   */
01489 
01490 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Fri Jan 13 2017 11:00:15 for STM32469I-Discovery BSP User Manual by   doxygen 1.7.6.1