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