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