Team Riedel - display

Dependencies:   LCD_fonts SPI_TFT_ILI9341 CMSIS_DSP_401_without_cm4 mbed-src SDFileSystem wavfile

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32l476g_discovery_audio.cpp Source File

stm32l476g_discovery_audio.cpp

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