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