STM32L152D_EVAL BSP User Manual
|
stm32l152d_eval_audio.c
Go to the documentation of this file.
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l152d_eval_audio.c 00004 * @author MCD Application Team 00005 * @brief This file provides the Audio driver for the STM32L152D-Eval 00006 * board. 00007 @verbatim 00008 ============================================================================== 00009 ##### How to use this driver ##### 00010 ============================================================================== 00011 [..] 00012 (#) This driver supports STM32L152xD devices on STM32L152D-Eval Kit: 00013 (++) to play an audio file (all functions names start by BSP_AUDIO_OUT_xxx) 00014 (++) to record an audio file through MP45DT02, ST MEMS (all functions names 00015 start by AUDIO_IN_xxx) 00016 00017 [..] 00018 (#) PLAY A FILE: 00019 (++) Call the function BSP_AUDIO_OUT_Init( 00020 OutputDevice: physical output mode (OUTPUT_DEVICE_SPEAKER, 00021 OUTPUT_DEVICE_HEADPHONE, OUTPUT_DEVICE_AUTO or 00022 OUTPUT_DEVICE_BOTH) 00023 Volume: initial volume to be set (0 is min (mute), 100 is max (100%) 00024 AudioFreq: Audio frequency in Hz (8000, 16000, 22500, 32000 ...) 00025 this parameter is relative to the audio file/stream type. 00026 ) 00027 This function configures all the hardware required for the audio application 00028 (codec, I2C, I2S, GPIOs, DMA and interrupt if needed). This function returns 0 00029 if configuration is OK. 00030 If the returned value is different from 0 or the function is stuck then the 00031 communication with the codec (try to un-plug the power or reset device in this case). 00032 (+++) OUTPUT_DEVICE_SPEAKER: only speaker will be set as output for the 00033 audio stream. 00034 (+++) OUTPUT_DEVICE_HEADPHONE: only headphones will be set as output for 00035 the audio stream. 00036 (+++) OUTPUT_DEVICE_AUTO: Selection of output device is made through external 00037 switch (implemented into the audio jack on the evaluation board). 00038 When the Headphone is connected it is used as output. 00039 When the headphone is disconnected from the audio jack, the output is 00040 automatically switched to Speaker. 00041 (+++) OUTPUT_DEVICE_BOTH: both Speaker and Headphone are used as outputs 00042 for the audio stream at the same time. 00043 (++) Call the function BSP_AUDIO_OUT_Play( 00044 pBuffer: pointer to the audio data file address 00045 Size: size of the buffer to be sent in Bytes 00046 ) 00047 to start playing (for the first time) from the audio file/stream. 00048 (++) Call the function BSP_AUDIO_OUT_Pause() to pause playing 00049 (++) Call the function BSP_AUDIO_OUT_Resume() to resume playing. 00050 Note. After calling BSP_AUDIO_OUT_Pause() function for pause, 00051 only BSP_AUDIO_OUT_Resume() should be called for resume 00052 (it is not allowed to call BSP_AUDIO_OUT_Play() in this case). 00053 Note. This function should be called only when the audio file is played 00054 or paused (not stopped). 00055 (++) For each mode, you may need to implement the relative callback functions 00056 into your code. 00057 The Callback functions are named BSP_AUDIO_OUT_XXXCallBack() and only 00058 their prototypes are declared in the stm32l152d_eval_audio.h file. 00059 (refer to the example for more details on the callbacks implementations) 00060 (++) To Stop playing, to modify the volume level, the frequency or to mute, 00061 use the functions BSP_AUDIO_OUT_Stop(), BSP_AUDIO_OUT_SetVolume(), 00062 AUDIO_OUT_SetFrequency() BSP_AUDIO_OUT_SetOutputMode and BSP_AUDIO_OUT_SetMute(). 00063 (++) The driver API and the callback functions are at the end of the 00064 stm32l152d_eval_audio.h file. 00065 00066 (++) This driver provide the High Audio Layer: consists of the function API 00067 exported in the stm32l152d_eval_audio.h file (BSP_AUDIO_OUT_Init(), 00068 BSP_AUDIO_OUT_Play() ...) 00069 (++) This driver provide also the Media Access Layer (MAL): which consists 00070 of functions allowing to access the media containing/providing the 00071 audio file/stream. These functions are also included as local functions into 00072 the stm32l152d_eval_audio.c file (I2SOUT_Init()...) 00073 00074 [..] 00075 (#) RECORD A FILE: 00076 (++) Call the function BSP_AUDIO_IN_Init( 00077 AudioFreq: Audio frequency in Hz (8000, 16000, 22500, 32000 ...) 00078 ) 00079 This function configures all the hardware required for the audio application (I2S, 00080 GPIOs, DMA and interrupt if needed). This function returns 0 if configuration is OK. 00081 00082 (++) Call the function BSP_AUDIO_IN_Record( 00083 pbuf Main buffer pointer for the recorded data storing 00084 size Current size of the recorded buffer 00085 ) 00086 to start recording from the microphone. 00087 00088 (++) User needs to implement user callbacks to retrieve data saved in the record buffer 00089 (AUDIO_IN_RxHalfCpltCallback/BSP_AUDIO_IN_ReceiveComplete_CallBack) 00090 00091 (++) Call the function AUDIO_IN_STOP() to stop recording 00092 00093 [..] 00094 ##### Known Limitations ##### 00095 ============================================================================== 00096 (#) When using the Speaker, if the audio file quality is not high enough, the 00097 speaker output may produce high and uncomfortable noise level. To avoid 00098 this issue, to use speaker output properly, try to increase audio file 00099 sampling rate (typically higher than 48KHz). 00100 This operation will lead to larger file size. 00101 00102 (#) Communication with the audio codec (through I2C) may be corrupted if it 00103 is interrupted by some user interrupt routines (in this case, interrupts 00104 could be disabled just before the start of communication then re-enabled 00105 when it is over). Note that this communication is only done at the 00106 configuration phase (BSP_AUDIO_OUT_Init() or BSP_AUDIO_OUT_Stop()) 00107 and when Volume control modification is performed (BSP_AUDIO_OUT_SetVolume() 00108 or BSP_AUDIO_OUT_SetMute()or BSP_AUDIO_OUT_SetOutputMode()). 00109 When the audio data is played, no communication is required with the audio codec. 00110 00111 (#) Parsing of audio file is not implemented (in order to determine audio file 00112 properties: Mono/Stereo, Data size, File size, Audio Frequency, Audio Data 00113 header size ...). The configuration is fixed for the given audio file. 00114 00115 (#) Mono audio streaming is not supported (in order to play mono audio streams, 00116 each data should be sent twice on the I2S or should be duplicated on the 00117 source buffer. Or convert the stream in stereo before playing). 00118 00119 (#) Supports only 16-bit audio data size. 00120 00121 @endverbatim 00122 ****************************************************************************** 00123 * @attention 00124 * 00125 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> 00126 * 00127 * Redistribution and use in source and binary forms, with or without modification, 00128 * are permitted provided that the following conditions are met: 00129 * 1. Redistributions of source code must retain the above copyright notice, 00130 * this list of conditions and the following disclaimer. 00131 * 2. Redistributions in binary form must reproduce the above copyright notice, 00132 * this list of conditions and the following disclaimer in the documentation 00133 * and/or other materials provided with the distribution. 00134 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00135 * may be used to endorse or promote products derived from this software 00136 * without specific prior written permission. 00137 * 00138 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00139 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00140 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00141 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00142 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00143 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00144 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00145 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00146 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00147 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00148 * 00149 ****************************************************************************** 00150 */ 00151 00152 /* Includes ------------------------------------------------------------------*/ 00153 #include "stm32l152d_eval_audio.h" 00154 00155 /** @addtogroup BSP 00156 * @{ 00157 */ 00158 00159 /** @addtogroup STM32L152D_EVAL 00160 * @{ 00161 */ 00162 00163 /** @defgroup STM32L152D_EVAL_AUDIO STM32L152D-EVAL Audio 00164 * @brief This file includes the low layer audio driver available on STM32L152D-Eval 00165 * eval board. 00166 * @{ 00167 */ 00168 00169 /** @defgroup STM32L152D_EVAL_AUDIO_Private_Variables Private Variables 00170 * @{ 00171 */ 00172 /*### PLAY ###*/ 00173 static AUDIO_DrvTypeDef *pAudioDrv; 00174 I2S_HandleTypeDef hAudioOutI2s; 00175 00176 /*### RECORD ###*/ 00177 OPAMP_HandleTypeDef hAudioInOpamp; 00178 00179 /* ADC channel configuration structure declaration */ 00180 ADC_HandleTypeDef hAudioInAdc; 00181 static ADC_ChannelConfTypeDef hAudioInConfigAdc; 00182 00183 TIM_HandleTypeDef hAudioInTim3; 00184 00185 __IO uint16_t AudioInVolume = DEFAULT_AUDIO_IN_VOLUME; 00186 00187 /** 00188 * @} 00189 */ 00190 00191 /** @defgroup STM32L152D_EVAL_AUDIO_Private_Functions Private Functions 00192 * @{ 00193 */ 00194 static void I2SOUT_MspInit(void); 00195 static void I2SOUT_Init(uint32_t AudioFreq); 00196 00197 static void ADCx_MspInit(ADC_HandleTypeDef *hadc); 00198 static void OPAMPx_MspInit(OPAMP_HandleTypeDef *hadc); 00199 static void TIMx_Base_MspInit(TIM_HandleTypeDef *hadc); 00200 00201 /** 00202 * @} 00203 */ 00204 00205 00206 /** @defgroup STM32L152D_EVAL_AUDIO_Exported_Functions Exported Functions 00207 * @{ 00208 */ 00209 00210 /** 00211 * @brief Configure the audio peripherals. 00212 * @param OutputDevice: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE, 00213 * OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO . 00214 * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max)) 00215 * @param AudioFreq: Audio frequency used to play the audio stream. 00216 * @retval 0 if correct communication, else wrong communication 00217 */ 00218 uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq) 00219 { 00220 uint8_t ret = AUDIO_ERROR; 00221 uint32_t deviceid = 0x00; 00222 00223 deviceid = cs43l22_drv.ReadID(AUDIO_I2C_ADDRESS); 00224 00225 if((deviceid & CS43L22_ID_MASK) == CS43L22_ID) 00226 { 00227 /* Initialize the audio driver structure */ 00228 pAudioDrv = &cs43l22_drv; 00229 ret = AUDIO_OK; 00230 } 00231 else 00232 { 00233 ret = AUDIO_ERROR; 00234 } 00235 00236 if(ret == AUDIO_OK) 00237 { 00238 pAudioDrv->Init(AUDIO_I2C_ADDRESS, OutputDevice, Volume, AudioFreq); 00239 /* I2S data transfer preparation: 00240 Prepare the Media to be used for the audio transfer from memory to I2S peripheral */ 00241 /* Configure the I2S peripheral */ 00242 I2SOUT_Init(AudioFreq); 00243 } 00244 00245 return ret; 00246 } 00247 00248 /** 00249 * @brief Starts playing audio stream from a data buffer for a determined size. 00250 * @param pBuffer: Pointer to the buffer 00251 * @param Size: Number of audio data BYTES. 00252 * @retval AUDIO_OK if correct communication, else wrong communication 00253 */ 00254 uint8_t BSP_AUDIO_OUT_Play(uint16_t* pBuffer, uint32_t Size) 00255 { 00256 /* Call the audio Codec Play function */ 00257 if(pAudioDrv->Play(AUDIO_I2C_ADDRESS, pBuffer, Size) != 0) 00258 { 00259 return AUDIO_ERROR; 00260 } 00261 else 00262 { 00263 /* Update the Media layer and enable it for play */ 00264 HAL_I2S_Transmit_DMA(&hAudioOutI2s, pBuffer, DMA_MAX(Size)); 00265 00266 return AUDIO_OK; 00267 } 00268 } 00269 00270 /** 00271 * @brief Sends n-Bytes on the I2S interface. 00272 * @param pData: pointer on data address 00273 * @param Size: number of data to be written 00274 * @retval None 00275 */ 00276 uint8_t BSP_AUDIO_OUT_ChangeBuffer(uint16_t *pData, uint16_t Size) 00277 { 00278 return (HAL_I2S_Transmit_DMA(&hAudioOutI2s, pData, Size)); 00279 } 00280 00281 /** 00282 * @brief This function Pauses the audio file stream. In case 00283 * of using DMA, the DMA Pause feature is used. 00284 * @note When calling BSP_AUDIO_OUT_Pause() function for pause, only 00285 * BSP_AUDIO_OUT_Resume() function should be called for resume (use of BSP_AUDIO_OUT_Play() 00286 * function for resume could lead to unexpected behavior). 00287 * @retval AUDIO_OK if correct communication, else wrong communication 00288 */ 00289 uint8_t BSP_AUDIO_OUT_Pause(void) 00290 { 00291 /* Call the Audio Codec Pause/Resume function */ 00292 if(pAudioDrv->Pause(AUDIO_I2C_ADDRESS) != 0) 00293 { 00294 return AUDIO_ERROR; 00295 } 00296 else 00297 { 00298 /* Call the Media layer pause function */ 00299 HAL_I2S_DMAPause(&hAudioOutI2s); 00300 00301 /* Return AUDIO_OK if all operations are OK */ 00302 return AUDIO_OK; 00303 } 00304 } 00305 00306 /** 00307 * @brief This function Resumes the audio file stream. 00308 * @note When calling BSP_AUDIO_OUT_Pause() function for pause, only 00309 * BSP_AUDIO_OUT_Resume() function should be called for resume (use of BSP_AUDIO_OUT_Play() 00310 * function for resume could lead to unexpected behavior). 00311 * @retval AUDIO_OK if correct communication, else wrong communication 00312 */ 00313 uint8_t BSP_AUDIO_OUT_Resume(void) 00314 { 00315 /* Call the Audio Codec Pause/Resume function */ 00316 if(pAudioDrv->Resume(AUDIO_I2C_ADDRESS) != 0) 00317 { 00318 return AUDIO_ERROR; 00319 } 00320 else 00321 { 00322 /* Call the Media layer resume function */ 00323 HAL_I2S_DMAResume(&hAudioOutI2s); 00324 /* Return AUDIO_OK if all operations are OK */ 00325 return AUDIO_OK; 00326 } 00327 } 00328 00329 /** 00330 * @brief Stops audio playing and Power down the Audio Codec. 00331 * @param Option: could be one of the following parameters 00332 * - CODEC_PDWN_HW: completely shut down the codec (physically). 00333 * Then need to reconfigure the Codec after power on. 00334 * @retval AUDIO_OK if correct communication, else wrong communication 00335 */ 00336 uint8_t BSP_AUDIO_OUT_Stop(uint32_t Option) 00337 { 00338 /* Call DMA Stop to disable DMA stream before stopping codec */ 00339 HAL_I2S_DMAStop(&hAudioOutI2s); 00340 00341 /* Call Audio Codec Stop function */ 00342 if(pAudioDrv->Stop(AUDIO_I2C_ADDRESS, Option) != 0) 00343 { 00344 return AUDIO_ERROR; 00345 } 00346 else 00347 { 00348 if(Option == CODEC_PDWN_HW) 00349 { 00350 /* Wait at least 100us */ 00351 HAL_Delay(1); 00352 00353 /* Reset The pin */ 00354 HAL_GPIO_WritePin(AUDIO_RESET_GPIO, AUDIO_RESET_PIN, GPIO_PIN_RESET); 00355 } 00356 /* Return AUDIO_OK when all operations are correctly done */ 00357 return AUDIO_OK; 00358 } 00359 } 00360 00361 /** 00362 * @brief Controls the current audio volume level. 00363 * @param Volume: Volume level to be set in percentage from 0% to 100% (0 for 00364 * Mute and 100 for Max volume level). 00365 * @retval AUDIO_OK if correct communication, else wrong communication 00366 */ 00367 uint8_t BSP_AUDIO_OUT_SetVolume(uint8_t Volume) 00368 { 00369 /* Call the codec volume control function with converted volume value */ 00370 if(pAudioDrv->SetVolume(AUDIO_I2C_ADDRESS, Volume) != 0) 00371 { 00372 return AUDIO_ERROR; 00373 } 00374 else 00375 { 00376 /* Return AUDIO_OK when all operations are correctly done */ 00377 return AUDIO_OK; 00378 } 00379 } 00380 00381 /** 00382 * @brief Enables or disables the MUTE mode by software 00383 * @param Cmd: could be AUDIO_MUTE_ON to mute sound or AUDIO_MUTE_OFF to 00384 * unmute the codec and restore previous volume level. 00385 * @retval AUDIO_OK if correct communication, else wrong communication 00386 */ 00387 uint8_t BSP_AUDIO_OUT_SetMute(uint32_t Cmd) 00388 { 00389 /* Call the Codec Mute function */ 00390 if(pAudioDrv->SetMute(AUDIO_I2C_ADDRESS, Cmd) != 0) 00391 { 00392 return AUDIO_ERROR; 00393 } 00394 else 00395 { 00396 /* Return AUDIO_OK when all operations are correctly done */ 00397 return AUDIO_OK; 00398 } 00399 } 00400 00401 /** 00402 * @brief Switch dynamically (while audio file is played) the output target 00403 * (speaker or headphone). 00404 * @note This function modifies a global variable of the audio codec driver: OutputDev. 00405 * @param Output: specifies the audio output target: OUTPUT_DEVICE_SPEAKER, 00406 * OUTPUT_DEVICE_HEADPHONE, OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO 00407 * @retval AUDIO_OK if correct communication, else wrong communication 00408 */ 00409 uint8_t BSP_AUDIO_OUT_SetOutputMode(uint8_t Output) 00410 { 00411 /* Call the Codec output Device function */ 00412 if(pAudioDrv->SetOutputMode(AUDIO_I2C_ADDRESS, Output) != 0) 00413 { 00414 return AUDIO_ERROR; 00415 } 00416 else 00417 { 00418 /* Return AUDIO_OK when all operations are correctly done */ 00419 return AUDIO_OK; 00420 } 00421 } 00422 00423 /** 00424 * @brief Update the audio frequency. 00425 * @param AudioFreq: Audio frequency used to play the audio stream. 00426 * @retval None 00427 * @note This API should be called after the BSP_AUDIO_OUT_Init() to adjust the 00428 * audio frequency. 00429 */ 00430 void BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq) 00431 { 00432 /* Update the I2S audio frequency configuration */ 00433 I2SOUT_Init(AudioFreq); 00434 } 00435 00436 /** 00437 * @brief Manages the DMA full Transfer complete event. 00438 * @retval None 00439 */ 00440 __weak void BSP_AUDIO_OUT_TransferComplete_CallBack(void) 00441 { 00442 } 00443 00444 /** 00445 * @brief Manages the DMA Half Transfer complete event. 00446 * @retval None 00447 */ 00448 __weak void BSP_AUDIO_OUT_HalfTransfer_CallBack(void) 00449 { 00450 } 00451 00452 /** 00453 * @brief Manages the DMA FIFO error event. 00454 * @retval None 00455 */ 00456 __weak void BSP_AUDIO_OUT_Error_CallBack(void) 00457 { 00458 } 00459 00460 /** 00461 * @brief Initialize wave recording 00462 * @param AudioFreq Audio frequency acquisition. 00463 * Note: On STM32L1 evaluation board, the microphone acquisition is 00464 * done through an analong amplifier with a band-pass filter 00465 * centered at 32kHz. 00466 * Therefore, this parameter value should be set at maximum 00467 * to 32kHz (value "32000"). 00468 * @param BitRes Audio frequency to be configured for the I2S peripheral. 00469 * Note: On STM32L1 evaluation board, this parameter is not used, but 00470 * kept as parameter for compatibility with other STM32 BSP 00471 * drivers. 00472 * @param ChnlNbr Audio frequency to be configured for the I2S peripheral. 00473 * Note: On STM32L1 evaluation board, this parameter is not used, but 00474 * kept as parameter for compatibility with other STM32 BSP 00475 * drivers. 00476 * @retval AUDIO_OK if correct communication, else wrong communication 00477 */ 00478 uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr) 00479 { 00480 00481 /*## Configure the OPAMP ###################################################*/ 00482 00483 /* Set OPAMP instance */ 00484 hAudioInOpamp.Instance = OPAMP1; 00485 00486 /* Configure the OPAMP if not already configured (on the first occurrence */ 00487 /* of this function (). */ 00488 if(HAL_OPAMP_GetState(&hAudioInOpamp) == HAL_OPAMP_STATE_RESET) 00489 { 00490 /* Configuration of OPAMP */ 00491 hAudioInOpamp.Init.Mode = OPAMP_STANDALONE_MODE; 00492 hAudioInOpamp.Init.NonInvertingInput = OPAMP_NONINVERTINGINPUT_IO0; 00493 hAudioInOpamp.Init.InvertingInput = OPAMP_INVERTINGINPUT_IO0; 00494 hAudioInOpamp.Init.PowerMode = OPAMP_POWERMODE_NORMAL; 00495 hAudioInOpamp.Init.PowerSupplyRange = OPAMP_POWERSUPPLY_HIGH; 00496 hAudioInOpamp.Init.UserTrimming = OPAMP_TRIMMING_FACTORY; 00497 00498 /* Init MSP of OPAMPx */ 00499 OPAMPx_MspInit(&hAudioInOpamp); 00500 00501 /* Init OPAMPx */ 00502 if (HAL_OPAMP_Init(&hAudioInOpamp) != HAL_OK) 00503 { 00504 return AUDIO_ERROR; 00505 } 00506 } 00507 00508 /* Enable OPAMPx */ 00509 if (HAL_OPAMP_Start(&hAudioInOpamp) != HAL_OK) 00510 { 00511 return AUDIO_ERROR; 00512 } 00513 00514 /*## Configure the ADC #####################################################*/ 00515 00516 /* Set ADC instance */ 00517 hAudioInAdc.Instance = ADC1; 00518 00519 /* Deinitialize the ADC peripheral registers to its default reset values */ 00520 HAL_ADC_DeInit(&hAudioInAdc); 00521 00522 /* Configure the ADC */ 00523 /* Configuration of ADCx init structure: ADC parameters and regular group */ 00524 hAudioInAdc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; /* ADC clock equal to HSI frequency: 16MHz */ 00525 hAudioInAdc.Init.Resolution = ADC_RESOLUTION_12B; 00526 hAudioInAdc.Init.DataAlign = ADC_DATAALIGN_RIGHT; 00527 hAudioInAdc.Init.ScanConvMode = DISABLE; /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */ 00528 hAudioInAdc.Init.EOCSelection = ADC_EOC_SEQ_CONV; 00529 hAudioInAdc.Init.LowPowerAutoWait = ADC_AUTOWAIT_DISABLE; 00530 hAudioInAdc.Init.LowPowerAutoPowerOff = ADC_AUTOPOWEROFF_DISABLE; 00531 hAudioInAdc.Init.ChannelsBank = ADC_CHANNELS_BANK_A; 00532 hAudioInAdc.Init.ContinuousConvMode = DISABLE; /* Continuous mode disabled to have only 1 conversion at each ADC external event trig */ 00533 hAudioInAdc.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T3_TRGO; /* Trig of conversion start done by external event */ 00534 hAudioInAdc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING; 00535 hAudioInAdc.Init.DMAContinuousRequests = ENABLE; 00536 00537 /* Init MSP of ADCx */ 00538 ADCx_MspInit(&hAudioInAdc); 00539 00540 /* Init ADCx */ 00541 if (HAL_ADC_Init(&hAudioInAdc) != HAL_OK) 00542 { 00543 return AUDIO_ERROR; 00544 } 00545 00546 /* Configuration of channel on ADCx regular group on rank 1 */ 00547 hAudioInConfigAdc.Channel = AUDIO_IN_ADC_CHANNEL; 00548 hAudioInConfigAdc.SamplingTime = ADC_SAMPLETIME_384CYCLES; /* With ADC frequency of 16MHz, conversion time will be 24.75us. This is compliant with sampling time of 32kHz (31.25us) or below */ 00549 hAudioInConfigAdc.Rank = ADC_REGULAR_RANK_1; 00550 HAL_ADC_ConfigChannel(&hAudioInAdc, &hAudioInConfigAdc); 00551 00552 00553 /*## Configure the Timer ###################################################*/ 00554 00555 /* Set TIM3 period to AudioFreq using system clock 32Mhz */ 00556 hAudioInTim3.Instance = TIM3; 00557 hAudioInTim3.Init.Period = (HAL_RCC_GetPCLK1Freq() / (AudioFreq)) -1; 00558 hAudioInTim3.Init.Prescaler = 0; 00559 hAudioInTim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; 00560 hAudioInTim3.Init.CounterMode = TIM_COUNTERMODE_UP; 00561 00562 /* Init MSP of TIMx */ 00563 TIMx_Base_MspInit(&hAudioInTim3); 00564 00565 /* Init TIMx time base */ 00566 HAL_TIM_Base_Init(&hAudioInTim3); 00567 00568 /* Return 0 if all operations are OK */ 00569 return AUDIO_OK; 00570 } 00571 00572 /** 00573 * @brief Start audio recording 00574 * @param pbuf Main buffer pointer for the recorded data storing 00575 * @param size Current size of the recorded buffer 00576 * @retval AUDIO_OK if correct communication, else wrong communication 00577 */ 00578 uint8_t BSP_AUDIO_IN_Record(uint16_t* pbuf, uint32_t size) 00579 { 00580 uint32_t ret = AUDIO_OK; 00581 TIM_MasterConfigTypeDef master_config = {0}; 00582 00583 if (HAL_ADC_Start_DMA(&hAudioInAdc, (uint32_t*)pbuf, size) == HAL_OK) 00584 { 00585 master_config.MasterOutputTrigger = TIM_TRGO_UPDATE; 00586 master_config.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; 00587 00588 HAL_TIMEx_MasterConfigSynchronization(&hAudioInTim3, &master_config); 00589 00590 /* Start the time base triggering the ADC */ 00591 if (HAL_TIM_Base_Start(&hAudioInTim3) != HAL_OK) 00592 { 00593 ret = AUDIO_ERROR; 00594 } 00595 } 00596 else 00597 { 00598 ret = AUDIO_ERROR; 00599 } 00600 00601 return ret; 00602 } 00603 00604 /** 00605 * @brief Stop audio recording 00606 * @retval None 00607 */ 00608 uint8_t BSP_AUDIO_IN_Stop(void) 00609 { 00610 uint32_t ret = AUDIO_OK; 00611 00612 /* Stop the time base triggering the ADC */ 00613 if (HAL_TIM_Base_Stop(&hAudioInTim3) != HAL_OK) 00614 { 00615 ret = AUDIO_ERROR; 00616 } 00617 00618 if (HAL_ADC_Stop_DMA(&hAudioInAdc) != HAL_OK) 00619 { 00620 /* Return 0 if all operations are OK */ 00621 ret = AUDIO_ERROR; 00622 } 00623 00624 /* Disable OPAMPx */ 00625 if (HAL_OPAMP_Stop(&hAudioInOpamp) != HAL_OK) 00626 { 00627 ret = AUDIO_ERROR; 00628 } 00629 00630 return ret; 00631 } 00632 00633 /** 00634 * @brief This function Pauses the audio file stream. 00635 * @retval AUDIO_OK if correct communication, else wrong communication 00636 */ 00637 uint8_t BSP_AUDIO_IN_Pause(void) 00638 { 00639 uint32_t ret = AUDIO_OK; 00640 00641 /* Stop the time base triggering the ADC */ 00642 if (HAL_TIM_Base_Stop(&hAudioInTim3) != HAL_OK) 00643 { 00644 ret = AUDIO_ERROR; 00645 } 00646 00647 /* Return AUDIO_OK if all operations are OK */ 00648 return ret; 00649 } 00650 00651 /** 00652 * @brief This function Resumes the audio file stream. 00653 * @retval AUDIO_OK if correct communication, else wrong communication 00654 */ 00655 uint8_t BSP_AUDIO_IN_Resume(void) 00656 { 00657 uint32_t ret = AUDIO_OK; 00658 00659 /* Start the time base triggering the ADC */ 00660 if (HAL_TIM_Base_Start(&hAudioInTim3) != HAL_OK) 00661 { 00662 ret = AUDIO_ERROR; 00663 } 00664 00665 /* Return AUDIO_OK if all operations are OK */ 00666 return ret; 00667 } 00668 00669 /** 00670 * @brief Controls the audio in volume level. 00671 * @param Volume: Volume level to be set in percentage from 0% to 100% (0 for 00672 * Mute and 100 for Max volume level). 00673 * @retval AUDIO_OK if correct communication, else wrong communication 00674 */ 00675 uint8_t BSP_AUDIO_IN_SetVolume(uint8_t Volume) 00676 { 00677 /* Set the Global variable AudioInVolume */ 00678 AudioInVolume = Volume; 00679 /* Return AUDIO_OK when all operations are correctly done */ 00680 return AUDIO_OK; 00681 } 00682 00683 /** 00684 * @brief User callback when record buffer is filled 00685 * @retval None 00686 */ 00687 __weak void BSP_AUDIO_IN_TransferComplete_CallBack(void) 00688 { 00689 /* This function should be implemented by the user application. 00690 It is called into this driver when the current buffer is filled 00691 to prepare the next buffer pointer and its size. */ 00692 } 00693 00694 /** 00695 * @brief Manages the DMA Half Transfer complete event. 00696 * @retval None 00697 */ 00698 __weak void BSP_AUDIO_IN_HalfTransfer_CallBack(void) 00699 { 00700 /* This function should be implemented by the user application. 00701 It is called into this driver when the current buffer is filled 00702 to prepare the next buffer pointer and its size. */ 00703 } 00704 00705 /** 00706 * @brief Audio IN Error callback function 00707 * @retval None 00708 */ 00709 __weak void BSP_AUDIO_IN_Error_Callback(void) 00710 { 00711 /* This function is called when an Interrupt due to transfer error on or peripheral 00712 error occurs. */ 00713 } 00714 00715 /** 00716 * @} 00717 */ 00718 00719 /** @addtogroup STM32L152D_EVAL_AUDIO_Private_Functions 00720 * @{ 00721 */ 00722 00723 /****************************************************************************** 00724 Static Function 00725 *******************************************************************************/ 00726 00727 /** 00728 * @brief AUDIO OUT I2S MSP Init 00729 * @retval None 00730 */ 00731 static void I2SOUT_MspInit(void) 00732 { 00733 static DMA_HandleTypeDef hdma_i2stx; 00734 GPIO_InitTypeDef gpioinitstruct = {0}; 00735 I2S_HandleTypeDef *hi2s = &hAudioOutI2s; 00736 00737 /* Enable I2SOUT clock */ 00738 I2SOUT_CLK_ENABLE(); 00739 00740 /*** Configure the GPIOs ***/ 00741 /* Enable I2S GPIO clocks */ 00742 I2SOUT_SCK_SD_CLK_ENABLE(); 00743 I2SOUT_WS_CLK_ENABLE(); 00744 00745 /* I2SOUT pins configuration: WS, SCK and SD pins -----------------------------*/ 00746 gpioinitstruct.Pin = I2SOUT_SCK_PIN | I2SOUT_SD_PIN; 00747 gpioinitstruct.Mode = GPIO_MODE_AF_PP; 00748 gpioinitstruct.Pull = GPIO_NOPULL; 00749 gpioinitstruct.Speed = GPIO_SPEED_FREQ_HIGH; 00750 gpioinitstruct.Alternate = I2SOUT_SCK_SD_WS_AF; 00751 HAL_GPIO_Init(I2SOUT_SCK_SD_GPIO_PORT, &gpioinitstruct); 00752 00753 gpioinitstruct.Pin = I2SOUT_WS_PIN ; 00754 HAL_GPIO_Init(I2SOUT_WS_GPIO_PORT, &gpioinitstruct); 00755 00756 /* I2SOUT pins configuration: MCK pin */ 00757 I2SOUT_MCK_CLK_ENABLE(); 00758 gpioinitstruct.Pin = I2SOUT_MCK_PIN; 00759 HAL_GPIO_Init(I2SOUT_MCK_GPIO_PORT, &gpioinitstruct); 00760 00761 /* Enable the I2S DMA clock */ 00762 I2SOUT_DMAx_CLK_ENABLE(); 00763 00764 if(hi2s->Instance == I2SOUT) 00765 { 00766 /* Configure the hdma_i2stx handle parameters */ 00767 hdma_i2stx.Init.Direction = DMA_MEMORY_TO_PERIPH; 00768 hdma_i2stx.Init.PeriphInc = DMA_PINC_DISABLE; 00769 hdma_i2stx.Init.MemInc = DMA_MINC_ENABLE; 00770 hdma_i2stx.Init.PeriphDataAlignment = I2SOUT_DMAx_PERIPH_DATA_SIZE; 00771 hdma_i2stx.Init.MemDataAlignment = I2SOUT_DMAx_MEM_DATA_SIZE; 00772 hdma_i2stx.Init.Mode = DMA_NORMAL; 00773 hdma_i2stx.Init.Priority = DMA_PRIORITY_HIGH; 00774 00775 hdma_i2stx.Instance = I2SOUT_DMAx_CHANNEL; 00776 00777 /* Associate the DMA handle */ 00778 __HAL_LINKDMA(hi2s, hdmatx, hdma_i2stx); 00779 00780 /* Deinitialize the Channel for new transfer */ 00781 HAL_DMA_DeInit(&hdma_i2stx); 00782 00783 /* Configure the DMA Channel */ 00784 HAL_DMA_Init(&hdma_i2stx); 00785 } 00786 00787 /* I2S DMA IRQ Channel configuration */ 00788 HAL_NVIC_SetPriority(I2SOUT_DMAx_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0); 00789 HAL_NVIC_EnableIRQ(I2SOUT_DMAx_IRQ); 00790 } 00791 00792 /** 00793 * @brief Initializes the Audio Codec audio interface (I2S) 00794 * @param AudioFreq: Audio frequency to be configured for the I2S peripheral. 00795 */ 00796 static void I2SOUT_Init(uint32_t AudioFreq) 00797 { 00798 /* Initialize the hAudioOutI2s Instance parameter */ 00799 hAudioOutI2s.Instance = I2SOUT; 00800 00801 /* Disable I2S block */ 00802 __HAL_I2S_DISABLE(&hAudioOutI2s); 00803 00804 /* I2SOUT peripheral configuration */ 00805 hAudioOutI2s.Init.AudioFreq = AudioFreq; 00806 hAudioOutI2s.Init.CPOL = I2S_CPOL_LOW; 00807 hAudioOutI2s.Init.DataFormat = I2S_DATAFORMAT_16B; 00808 hAudioOutI2s.Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE; 00809 hAudioOutI2s.Init.Mode = I2S_MODE_MASTER_TX; 00810 hAudioOutI2s.Init.Standard = I2S_STANDARD; 00811 /* Initialize the I2S peripheral with the structure above */ 00812 if(HAL_I2S_GetState(&hAudioOutI2s) == HAL_I2S_STATE_RESET) 00813 { 00814 I2SOUT_MspInit(); 00815 } 00816 00817 HAL_I2S_Init(&hAudioOutI2s); 00818 } 00819 00820 /** 00821 * @} 00822 */ 00823 00824 /** @defgroup STM32L152D_EVAL_AUDIO_Exported_Functions Exported Functions 00825 * @{ 00826 */ 00827 00828 /** 00829 * @brief Initializes ADC MSP. 00830 * @param hadc : ADC handle 00831 * @retval None 00832 */ 00833 static void ADCx_MspInit(ADC_HandleTypeDef *hadc) 00834 { 00835 static DMA_HandleTypeDef hdma_adc; 00836 GPIO_InitTypeDef gpioinitstruct = {0}; 00837 RCC_OscInitTypeDef oscinitstruct = {0}; 00838 00839 /*** Configure the GPIOs ***/ 00840 /* Configure pin corresponding to the selected ADC Channel as analog input */ 00841 /* Enable GPIO clock */ 00842 AUDIO_IN_ADC_GPIO_CLK_ENABLE(); 00843 00844 gpioinitstruct.Pin = AUDIO_IN_ADC_PIN; 00845 gpioinitstruct.Mode = GPIO_MODE_ANALOG; 00846 gpioinitstruct.Pull = GPIO_NOPULL; 00847 gpioinitstruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; 00848 HAL_GPIO_Init(AUDIO_IN_ADC_PORT, &gpioinitstruct); 00849 00850 /*** Configure the ADC peripheral ***/ 00851 00852 /* Enable asynchronous clock source of ADCx */ 00853 HAL_RCC_GetOscConfig(&oscinitstruct); 00854 oscinitstruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; 00855 oscinitstruct.HSIState = RCC_HSI_ON; 00856 oscinitstruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; 00857 HAL_RCC_OscConfig(&oscinitstruct); 00858 00859 /* Enable ADC clock */ 00860 __HAL_RCC_ADC1_CLK_ENABLE(); 00861 00862 /* DMA clock enable */ 00863 AUDIO_IN_DMAx_CLK_ENABLE(); 00864 00865 /* Configure DMA handle init parameters */ 00866 hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY; 00867 hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE; 00868 hdma_adc.Init.MemInc = DMA_MINC_ENABLE; 00869 hdma_adc.Init.PeriphDataAlignment = AUDIO_IN_DMAx_PERIPH_DATA_SIZE; 00870 hdma_adc.Init.MemDataAlignment = AUDIO_IN_DMAx_MEM_DATA_SIZE; 00871 hdma_adc.Init.Mode = DMA_CIRCULAR; 00872 hdma_adc.Init.Priority = DMA_PRIORITY_HIGH; 00873 hdma_adc.Instance = AUDIO_IN_DMAx_CHANNEL; 00874 00875 /* Associate the DMA handle */ 00876 __HAL_LINKDMA(hadc, DMA_Handle, hdma_adc); 00877 00878 /* Deinitialize the Channel for new transfer */ 00879 HAL_DMA_DeInit(&hdma_adc); 00880 00881 /* Configure the DMA Channel */ 00882 HAL_DMA_Init(&hdma_adc); 00883 00884 /* ADC DMA IRQ Channel configuration */ 00885 HAL_NVIC_SetPriority(AUDIO_IN_DMAx_IRQ, AUDIO_IN_IRQ_PREPRIO, 0); 00886 HAL_NVIC_EnableIRQ(AUDIO_IN_DMAx_IRQ); 00887 } 00888 00889 /** 00890 * @brief Initializes the OPAMP BSP. 00891 * @param hopamp : OPAMP handle 00892 * @retval None 00893 */ 00894 void OPAMPx_MspInit(OPAMP_HandleTypeDef* hopamp) 00895 { 00896 GPIO_InitTypeDef gpioinitstruct = {0}; 00897 00898 /*** Configure the GPIOs ***/ 00899 /* Enable GPIO clock */ 00900 AUDIO_IN_OPAMP_GPIO_CLK_ENABLE(); 00901 00902 gpioinitstruct.Pin = AUDIO_IN_OPAMP_PIN; 00903 gpioinitstruct.Mode = GPIO_MODE_ANALOG; 00904 gpioinitstruct.Pull = GPIO_NOPULL; 00905 gpioinitstruct.Speed = GPIO_SPEED_FREQ_HIGH; 00906 HAL_GPIO_Init(AUDIO_IN_OPAMP_PORT, &gpioinitstruct); 00907 00908 /*** Configure the OPAMP peripheral ***/ 00909 /* Enable OPAMP clock */ 00910 __HAL_RCC_OPAMP_CLK_ENABLE(); 00911 } 00912 00913 /** 00914 * @brief Tx Transfer completed callbacks 00915 * @param hi2s: I2S handle 00916 * @retval None 00917 */ 00918 void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s) 00919 { 00920 if(hi2s->Instance == I2SOUT) 00921 { 00922 /* Call the user function which will manage directly transfer complete*/ 00923 BSP_AUDIO_OUT_TransferComplete_CallBack(); 00924 } 00925 } 00926 00927 /** 00928 * @brief Tx Transfer Half completed callbacks 00929 * @param hi2s: I2S handle 00930 * @retval None 00931 */ 00932 void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s) 00933 { 00934 if(hi2s->Instance == I2SOUT) 00935 { 00936 /* Manage the remaining file size and new address offset: This function 00937 should be coded by user (its prototype is already declared in stm32l152d_eval_audio.h) */ 00938 BSP_AUDIO_OUT_HalfTransfer_CallBack(); 00939 } 00940 } 00941 00942 /** 00943 * @brief I2S error callbacks 00944 * @param hi2s: I2S handle 00945 * @retval None 00946 */ 00947 void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s) 00948 { 00949 /* Manage the error generated on DMA FIFO: This function 00950 should be coded by user (its prototype is already declared in stm32l152d_eval_audio.h) */ 00951 if(hi2s->Instance == I2SOUT) 00952 { 00953 BSP_AUDIO_OUT_Error_CallBack(); 00954 } 00955 } 00956 00957 /** 00958 * @brief Initializes the TIM Base BSP. 00959 * @param htim : Timer handle 00960 * @retval None 00961 */ 00962 void TIMx_Base_MspInit(TIM_HandleTypeDef* htim) 00963 { 00964 if (htim->Instance == TIM3) 00965 { 00966 __HAL_RCC_TIM3_CLK_ENABLE(); 00967 } 00968 } 00969 00970 /** 00971 * @brief Conversion complete callback in non blocking mode 00972 * @param hadc: ADC handle 00973 * @retval None 00974 */ 00975 void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) 00976 { 00977 BSP_AUDIO_IN_TransferComplete_CallBack(); 00978 } 00979 00980 /** 00981 * @brief Conversion DMA half-transfer callback in non blocking mode 00982 * @param hadc: ADC handle 00983 * @retval None 00984 */ 00985 void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc) 00986 { 00987 BSP_AUDIO_IN_HalfTransfer_CallBack(); 00988 } 00989 00990 /** 00991 * @} 00992 */ 00993 00994 /** 00995 * @} 00996 */ 00997 00998 /** 00999 * @} 01000 */ 01001 01002 /** 01003 * @} 01004 */ 01005 01006 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Thu Aug 24 2017 17:57:47 for STM32L152D_EVAL BSP User Manual by 1.7.6.1