STM32L152D_EVAL BSP User Manual: stm32l152d_eval_audio.c Source File

STM32L152D_EVAL BSP

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>&copy; 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   doxygen 1.7.6.1