.

Fork of BSP_DISCO_F746NG by ST

Committer:
shoaib_ahmed
Date:
Mon Jul 31 09:50:10 2017 +0000
Revision:
10:65aafc10c66e
Parent:
2:458ab1edf6b2
Child:
3:8ae03419c0f3
.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bcostm 1:ee089790cdbb 1 /**
bcostm 1:ee089790cdbb 2 ******************************************************************************
bcostm 1:ee089790cdbb 3 * @file stm32746g_discovery_audio.c
bcostm 1:ee089790cdbb 4 * @author MCD Application Team
bcostm 1:ee089790cdbb 5 * @version V1.0.0
bcostm 1:ee089790cdbb 6 * @date 25-June-2015
bcostm 1:ee089790cdbb 7 * @brief This file provides the Audio driver for the STM32746G-Discovery board.
bcostm 1:ee089790cdbb 8 @verbatim
bcostm 1:ee089790cdbb 9 How To use this driver:
bcostm 1:ee089790cdbb 10 -----------------------
bcostm 1:ee089790cdbb 11 + This driver supports STM32F7xx devices on STM32746G-Discovery (MB1191) board.
bcostm 1:ee089790cdbb 12 + Call the function BSP_AUDIO_OUT_Init(
bcostm 1:ee089790cdbb 13 OutputDevice: physical output mode (OUTPUT_DEVICE_SPEAKER,
bcostm 1:ee089790cdbb 14 OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH)
bcostm 1:ee089790cdbb 15 Volume : Initial volume to be set (0 is min (mute), 100 is max (100%)
bcostm 1:ee089790cdbb 16 AudioFreq : Audio frequency in Hz (8000, 16000, 22500, 32000...)
bcostm 1:ee089790cdbb 17 this parameter is relative to the audio file/stream type.
bcostm 1:ee089790cdbb 18 )
bcostm 1:ee089790cdbb 19 This function configures all the hardware required for the audio application (codec, I2C, SAI,
bcostm 1:ee089790cdbb 20 GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if configuration is OK.
bcostm 1:ee089790cdbb 21 If the returned value is different from AUDIO_OK or the function is stuck then the communication with
bcostm 1:ee089790cdbb 22 the codec or the MFX has failed (try to un-plug the power or reset device in this case).
bcostm 1:ee089790cdbb 23 - OUTPUT_DEVICE_SPEAKER : only speaker will be set as output for the audio stream.
bcostm 1:ee089790cdbb 24 - OUTPUT_DEVICE_HEADPHONE: only headphones will be set as output for the audio stream.
bcostm 1:ee089790cdbb 25 - OUTPUT_DEVICE_BOTH : both Speaker and Headphone are used as outputs for the audio stream
bcostm 1:ee089790cdbb 26 at the same time.
bcostm 1:ee089790cdbb 27 Note. On STM32746G-Discovery SAI_DMA is configured in CIRCULAR mode. Due to this the application
bcostm 1:ee089790cdbb 28 does NOT need to call BSP_AUDIO_OUT_ChangeBuffer() to assure streaming.
bcostm 1:ee089790cdbb 29 + Call the function BSP_DISCOVERY_AUDIO_OUT_Play(
bcostm 1:ee089790cdbb 30 pBuffer: pointer to the audio data file address
bcostm 1:ee089790cdbb 31 Size : size of the buffer to be sent in Bytes
bcostm 1:ee089790cdbb 32 )
bcostm 1:ee089790cdbb 33 to start playing (for the first time) from the audio file/stream.
bcostm 1:ee089790cdbb 34 + Call the function BSP_AUDIO_OUT_Pause() to pause playing
bcostm 1:ee089790cdbb 35 + Call the function BSP_AUDIO_OUT_Resume() to resume playing.
bcostm 1:ee089790cdbb 36 Note. After calling BSP_AUDIO_OUT_Pause() function for pause, only BSP_AUDIO_OUT_Resume() should be called
bcostm 1:ee089790cdbb 37 for resume (it is not allowed to call BSP_AUDIO_OUT_Play() in this case).
bcostm 1:ee089790cdbb 38 Note. This function should be called only when the audio file is played or paused (not stopped).
bcostm 1:ee089790cdbb 39 + For each mode, you may need to implement the relative callback functions into your code.
bcostm 1:ee089790cdbb 40 The Callback functions are named AUDIO_OUT_XXX_CallBack() and only their prototypes are declared in
bcostm 1:ee089790cdbb 41 the stm32746g_discovery_audio.h file. (refer to the example for more details on the callbacks implementations)
bcostm 1:ee089790cdbb 42 + To Stop playing, to modify the volume level, the frequency, the audio frame slot,
bcostm 1:ee089790cdbb 43 the device output mode the mute or the stop, use the functions: BSP_AUDIO_OUT_SetVolume(),
bcostm 1:ee089790cdbb 44 AUDIO_OUT_SetFrequency(), BSP_AUDIO_OUT_SetAudioFrameSlot(), BSP_AUDIO_OUT_SetOutputMode(),
bcostm 1:ee089790cdbb 45 BSP_AUDIO_OUT_SetMute() and BSP_AUDIO_OUT_Stop().
bcostm 1:ee089790cdbb 46 + The driver API and the callback functions are at the end of the stm32746g_discovery_audio.h file.
bcostm 1:ee089790cdbb 47
bcostm 1:ee089790cdbb 48 Driver architecture:
bcostm 1:ee089790cdbb 49 --------------------
bcostm 1:ee089790cdbb 50 + This driver provides the High Audio Layer: consists of the function API exported in the stm32746g_discovery_audio.h file
bcostm 1:ee089790cdbb 51 (BSP_AUDIO_OUT_Init(), BSP_AUDIO_OUT_Play() ...)
bcostm 1:ee089790cdbb 52 + This driver provide also the Media Access Layer (MAL): which consists of functions allowing to access the media containing/
bcostm 1:ee089790cdbb 53 providing the audio file/stream. These functions are also included as local functions into
bcostm 1:ee089790cdbb 54 the stm32746g_discovery_audio_codec.c file (SAIx_Out_Init() and SAIx_Out_DeInit(), SAIx_In_Init() and SAIx_In_DeInit())
bcostm 1:ee089790cdbb 55
bcostm 1:ee089790cdbb 56 Known Limitations:
bcostm 1:ee089790cdbb 57 ------------------
bcostm 1:ee089790cdbb 58 1- If the TDM Format used to play in parallel 2 audio Stream (the first Stream is configured in codec SLOT0 and second
bcostm 1:ee089790cdbb 59 Stream in SLOT1) the Pause/Resume, volume and mute feature will control the both streams.
bcostm 1:ee089790cdbb 60 2- Parsing of audio file is not implemented (in order to determine audio file properties: Mono/Stereo, Data size,
bcostm 1:ee089790cdbb 61 File size, Audio Frequency, Audio Data header size ...). The configuration is fixed for the given audio file.
bcostm 1:ee089790cdbb 62 3- Supports only Stereo audio streaming.
bcostm 1:ee089790cdbb 63 4- Supports only 16-bits audio data size.
bcostm 1:ee089790cdbb 64 @endverbatim
bcostm 1:ee089790cdbb 65 ******************************************************************************
bcostm 1:ee089790cdbb 66 * @attention
bcostm 1:ee089790cdbb 67 *
bcostm 1:ee089790cdbb 68 * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
bcostm 1:ee089790cdbb 69 *
bcostm 1:ee089790cdbb 70 * Redistribution and use in source and binary forms, with or without modification,
bcostm 1:ee089790cdbb 71 * are permitted provided that the following conditions are met:
bcostm 1:ee089790cdbb 72 * 1. Redistributions of source code must retain the above copyright notice,
bcostm 1:ee089790cdbb 73 * this list of conditions and the following disclaimer.
bcostm 1:ee089790cdbb 74 * 2. Redistributions in binary form must reproduce the above copyright notice,
bcostm 1:ee089790cdbb 75 * this list of conditions and the following disclaimer in the documentation
bcostm 1:ee089790cdbb 76 * and/or other materials provided with the distribution.
bcostm 1:ee089790cdbb 77 * 3. Neither the name of STMicroelectronics nor the names of its contributors
bcostm 1:ee089790cdbb 78 * may be used to endorse or promote products derived from this software
bcostm 1:ee089790cdbb 79 * without specific prior written permission.
bcostm 1:ee089790cdbb 80 *
bcostm 1:ee089790cdbb 81 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
bcostm 1:ee089790cdbb 82 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
bcostm 1:ee089790cdbb 83 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
bcostm 1:ee089790cdbb 84 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
bcostm 1:ee089790cdbb 85 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
bcostm 1:ee089790cdbb 86 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
bcostm 1:ee089790cdbb 87 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
bcostm 1:ee089790cdbb 88 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
bcostm 1:ee089790cdbb 89 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
bcostm 1:ee089790cdbb 90 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
bcostm 1:ee089790cdbb 91 *
bcostm 1:ee089790cdbb 92 ******************************************************************************
bcostm 1:ee089790cdbb 93 */
bcostm 1:ee089790cdbb 94
bcostm 1:ee089790cdbb 95 /* Includes ------------------------------------------------------------------*/
bcostm 1:ee089790cdbb 96 #include "stm32746g_discovery_audio.h"
bcostm 1:ee089790cdbb 97
bcostm 1:ee089790cdbb 98 /** @addtogroup BSP
bcostm 1:ee089790cdbb 99 * @{
bcostm 1:ee089790cdbb 100 */
bcostm 1:ee089790cdbb 101
bcostm 1:ee089790cdbb 102 /** @addtogroup STM32746G_DISCOVERY
bcostm 1:ee089790cdbb 103 * @{
bcostm 1:ee089790cdbb 104 */
bcostm 1:ee089790cdbb 105
bcostm 1:ee089790cdbb 106 /** @defgroup STM32746G_DISCOVERY_AUDIO STM32746G_DISCOVERY AUDIO
bcostm 1:ee089790cdbb 107 * @brief This file includes the low layer driver for wm8994 Audio Codec
bcostm 1:ee089790cdbb 108 * available on STM32746G-Discovery board(MB1191).
bcostm 1:ee089790cdbb 109 * @{
bcostm 1:ee089790cdbb 110 */
bcostm 1:ee089790cdbb 111
bcostm 1:ee089790cdbb 112 /** @defgroup STM32746G_DISCOVERY_AUDIO_Private_Types STM32746G_DISCOVERY AUDIO Private Types
bcostm 1:ee089790cdbb 113 * @{
bcostm 1:ee089790cdbb 114 */
bcostm 1:ee089790cdbb 115 /**
bcostm 1:ee089790cdbb 116 * @}
bcostm 1:ee089790cdbb 117 */
bcostm 1:ee089790cdbb 118
bcostm 1:ee089790cdbb 119 /** @defgroup STM32746G_DISCOVERY_AUDIO_Private_Defines STM32746G_DISCOVERY AUDIO Private Defines
bcostm 1:ee089790cdbb 120 * @{
bcostm 1:ee089790cdbb 121 */
bcostm 1:ee089790cdbb 122 /**
bcostm 1:ee089790cdbb 123 * @}
bcostm 1:ee089790cdbb 124 */
bcostm 1:ee089790cdbb 125
bcostm 1:ee089790cdbb 126 /** @defgroup STM32746G_DISCOVERY_AUDIO_Private_Macros STM32746G_DISCOVERY AUDIO Private Macros
bcostm 1:ee089790cdbb 127 * @{
bcostm 1:ee089790cdbb 128 */
bcostm 1:ee089790cdbb 129 /**
bcostm 1:ee089790cdbb 130 * @}
bcostm 1:ee089790cdbb 131 */
bcostm 1:ee089790cdbb 132
bcostm 1:ee089790cdbb 133 /** @defgroup STM32746G_DISCOVERY_AUDIO_Private_Variables STM32746G_DISCOVERY AUDIO Private Variables
bcostm 1:ee089790cdbb 134 * @{
bcostm 1:ee089790cdbb 135 */
bcostm 1:ee089790cdbb 136 AUDIO_DrvTypeDef *audio_drv;
bcostm 1:ee089790cdbb 137 SAI_HandleTypeDef haudio_out_sai={0};
bcostm 1:ee089790cdbb 138 SAI_HandleTypeDef haudio_in_sai={0};
bcostm 1:ee089790cdbb 139 TIM_HandleTypeDef haudio_tim;
bcostm 1:ee089790cdbb 140
bcostm 1:ee089790cdbb 141 uint16_t __IO AudioInVolume = DEFAULT_AUDIO_IN_VOLUME;
bcostm 1:ee089790cdbb 142
bcostm 1:ee089790cdbb 143 /**
bcostm 1:ee089790cdbb 144 * @}
bcostm 1:ee089790cdbb 145 */
bcostm 1:ee089790cdbb 146
bcostm 1:ee089790cdbb 147 /** @defgroup STM32746G_DISCOVERY_AUDIO_Private_Function_Prototypes STM32746G_DISCOVERY AUDIO Private Function Prototypes
bcostm 1:ee089790cdbb 148 * @{
bcostm 1:ee089790cdbb 149 */
adustm 2:458ab1edf6b2 150 static void AUDIO_IN_INT_IRQHandler(void);
adustm 2:458ab1edf6b2 151 static void AUDIO_IN_SAIx_DMAx_IRQHandler(void);
adustm 2:458ab1edf6b2 152 static void AUDIO_OUT_SAIx_DMAx_IRQHandler(void);
bcostm 1:ee089790cdbb 153 static void SAIx_Out_Init(uint32_t AudioFreq);
bcostm 1:ee089790cdbb 154 static void SAIx_Out_DeInit(void);
bcostm 1:ee089790cdbb 155 static void SAIx_In_Init(uint32_t SaiOutMode, uint32_t SlotActive, uint32_t AudioFreq);
bcostm 1:ee089790cdbb 156 static void SAIx_In_DeInit(void);
bcostm 1:ee089790cdbb 157 /**
bcostm 1:ee089790cdbb 158 * @}
bcostm 1:ee089790cdbb 159 */
bcostm 1:ee089790cdbb 160
bcostm 1:ee089790cdbb 161 /** @defgroup STM32746G_DISCOVERY_AUDIO_OUT_Exported_Functions STM32746G_DISCOVERY AUDIO Out Exported Functions
bcostm 1:ee089790cdbb 162 * @{
bcostm 1:ee089790cdbb 163 */
bcostm 1:ee089790cdbb 164
bcostm 1:ee089790cdbb 165 /**
bcostm 1:ee089790cdbb 166 * @brief Configures the audio peripherals.
bcostm 1:ee089790cdbb 167 * @param OutputDevice: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
bcostm 1:ee089790cdbb 168 * or OUTPUT_DEVICE_BOTH.
bcostm 1:ee089790cdbb 169 * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max))
bcostm 1:ee089790cdbb 170 * @param AudioFreq: Audio frequency used to play the audio stream.
bcostm 1:ee089790cdbb 171 * @note The I2S PLL input clock must be done in the user application.
bcostm 1:ee089790cdbb 172 * @retval AUDIO_OK if correct communication, else wrong communication
bcostm 1:ee089790cdbb 173 */
bcostm 1:ee089790cdbb 174 uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq)
bcostm 1:ee089790cdbb 175 {
bcostm 1:ee089790cdbb 176 uint8_t ret = AUDIO_ERROR;
bcostm 1:ee089790cdbb 177 uint32_t deviceid = 0x00;
bcostm 1:ee089790cdbb 178
bcostm 1:ee089790cdbb 179 /* Disable SAI */
bcostm 1:ee089790cdbb 180 SAIx_Out_DeInit();
bcostm 1:ee089790cdbb 181
bcostm 1:ee089790cdbb 182 /* PLL clock is set depending on the AudioFreq (44.1khz vs 48khz groups) */
bcostm 1:ee089790cdbb 183 BSP_AUDIO_OUT_ClockConfig(&haudio_out_sai, AudioFreq, NULL);
bcostm 1:ee089790cdbb 184
bcostm 1:ee089790cdbb 185 /* SAI data transfer preparation:
bcostm 1:ee089790cdbb 186 Prepare the Media to be used for the audio transfer from memory to SAI peripheral */
bcostm 1:ee089790cdbb 187 haudio_out_sai.Instance = AUDIO_OUT_SAIx;
bcostm 1:ee089790cdbb 188 if(HAL_SAI_GetState(&haudio_out_sai) == HAL_SAI_STATE_RESET)
bcostm 1:ee089790cdbb 189 {
bcostm 1:ee089790cdbb 190 /* Init the SAI MSP: this __weak function can be redefined by the application*/
bcostm 1:ee089790cdbb 191 BSP_AUDIO_OUT_MspInit(&haudio_out_sai, NULL);
bcostm 1:ee089790cdbb 192 }
bcostm 1:ee089790cdbb 193 SAIx_Out_Init(AudioFreq);
bcostm 1:ee089790cdbb 194
bcostm 1:ee089790cdbb 195 /* wm8994 codec initialization */
bcostm 1:ee089790cdbb 196 deviceid = wm8994_drv.ReadID(AUDIO_I2C_ADDRESS);
bcostm 1:ee089790cdbb 197
bcostm 1:ee089790cdbb 198 if((deviceid) == WM8994_ID)
bcostm 1:ee089790cdbb 199 {
bcostm 1:ee089790cdbb 200 /* Reset the Codec Registers */
bcostm 1:ee089790cdbb 201 wm8994_drv.Reset(AUDIO_I2C_ADDRESS);
bcostm 1:ee089790cdbb 202 /* Initialize the audio driver structure */
bcostm 1:ee089790cdbb 203 audio_drv = &wm8994_drv;
bcostm 1:ee089790cdbb 204 ret = AUDIO_OK;
bcostm 1:ee089790cdbb 205 }
bcostm 1:ee089790cdbb 206 else
bcostm 1:ee089790cdbb 207 {
bcostm 1:ee089790cdbb 208 ret = AUDIO_ERROR;
bcostm 1:ee089790cdbb 209 }
bcostm 1:ee089790cdbb 210
bcostm 1:ee089790cdbb 211 if(ret == AUDIO_OK)
bcostm 1:ee089790cdbb 212 {
bcostm 1:ee089790cdbb 213 /* Initialize the codec internal registers */
bcostm 1:ee089790cdbb 214 audio_drv->Init(AUDIO_I2C_ADDRESS, OutputDevice, Volume, AudioFreq);
bcostm 1:ee089790cdbb 215 }
bcostm 1:ee089790cdbb 216
bcostm 1:ee089790cdbb 217 return ret;
bcostm 1:ee089790cdbb 218 }
bcostm 1:ee089790cdbb 219
bcostm 1:ee089790cdbb 220 /**
bcostm 1:ee089790cdbb 221 * @brief Starts playing audio stream from a data buffer for a determined size.
bcostm 1:ee089790cdbb 222 * @param pBuffer: Pointer to the buffer
bcostm 1:ee089790cdbb 223 * @param Size: Number of audio data in BYTES unit.
bcostm 1:ee089790cdbb 224 * In memory, first element is for left channel, second element is for right channel
bcostm 1:ee089790cdbb 225 * @retval AUDIO_OK if correct communication, else wrong communication
bcostm 1:ee089790cdbb 226 */
bcostm 1:ee089790cdbb 227 uint8_t BSP_AUDIO_OUT_Play(uint16_t* pBuffer, uint32_t Size)
bcostm 1:ee089790cdbb 228 {
bcostm 1:ee089790cdbb 229 /* Call the audio Codec Play function */
bcostm 1:ee089790cdbb 230 if(audio_drv->Play(AUDIO_I2C_ADDRESS, pBuffer, Size) != 0)
bcostm 1:ee089790cdbb 231 {
bcostm 1:ee089790cdbb 232 return AUDIO_ERROR;
bcostm 1:ee089790cdbb 233 }
bcostm 1:ee089790cdbb 234 else
bcostm 1:ee089790cdbb 235 {
bcostm 1:ee089790cdbb 236 /* Update the Media layer and enable it for play */
bcostm 1:ee089790cdbb 237 HAL_SAI_Transmit_DMA(&haudio_out_sai, (uint8_t*) pBuffer, DMA_MAX(Size / AUDIODATA_SIZE));
bcostm 1:ee089790cdbb 238
bcostm 1:ee089790cdbb 239 return AUDIO_OK;
bcostm 1:ee089790cdbb 240 }
bcostm 1:ee089790cdbb 241 }
bcostm 1:ee089790cdbb 242
bcostm 1:ee089790cdbb 243 /**
bcostm 1:ee089790cdbb 244 * @brief Sends n-Bytes on the SAI interface.
bcostm 1:ee089790cdbb 245 * @param pData: pointer on data address
bcostm 1:ee089790cdbb 246 * @param Size: number of data to be written
bcostm 1:ee089790cdbb 247 * @retval None
bcostm 1:ee089790cdbb 248 */
bcostm 1:ee089790cdbb 249 void BSP_AUDIO_OUT_ChangeBuffer(uint16_t *pData, uint16_t Size)
bcostm 1:ee089790cdbb 250 {
bcostm 1:ee089790cdbb 251 HAL_SAI_Transmit_DMA(&haudio_out_sai, (uint8_t*) pData, Size);
bcostm 1:ee089790cdbb 252 }
bcostm 1:ee089790cdbb 253
bcostm 1:ee089790cdbb 254 /**
bcostm 1:ee089790cdbb 255 * @brief This function Pauses the audio file stream. In case
bcostm 1:ee089790cdbb 256 * of using DMA, the DMA Pause feature is used.
bcostm 1:ee089790cdbb 257 * @note When calling BSP_AUDIO_OUT_Pause() function for pause, only
bcostm 1:ee089790cdbb 258 * BSP_AUDIO_OUT_Resume() function should be called for resume (use of BSP_AUDIO_OUT_Play()
bcostm 1:ee089790cdbb 259 * function for resume could lead to unexpected behaviour).
bcostm 1:ee089790cdbb 260 * @retval AUDIO_OK if correct communication, else wrong communication
bcostm 1:ee089790cdbb 261 */
bcostm 1:ee089790cdbb 262 uint8_t BSP_AUDIO_OUT_Pause(void)
bcostm 1:ee089790cdbb 263 {
bcostm 1:ee089790cdbb 264 /* Call the Audio Codec Pause/Resume function */
bcostm 1:ee089790cdbb 265 if(audio_drv->Pause(AUDIO_I2C_ADDRESS) != 0)
bcostm 1:ee089790cdbb 266 {
bcostm 1:ee089790cdbb 267 return AUDIO_ERROR;
bcostm 1:ee089790cdbb 268 }
bcostm 1:ee089790cdbb 269 else
bcostm 1:ee089790cdbb 270 {
bcostm 1:ee089790cdbb 271 /* Call the Media layer pause function */
bcostm 1:ee089790cdbb 272 HAL_SAI_DMAPause(&haudio_out_sai);
bcostm 1:ee089790cdbb 273
bcostm 1:ee089790cdbb 274 /* Return AUDIO_OK when all operations are correctly done */
bcostm 1:ee089790cdbb 275 return AUDIO_OK;
bcostm 1:ee089790cdbb 276 }
bcostm 1:ee089790cdbb 277 }
bcostm 1:ee089790cdbb 278
bcostm 1:ee089790cdbb 279 /**
bcostm 1:ee089790cdbb 280 * @brief This function Resumes the audio file stream.
bcostm 1:ee089790cdbb 281 * @note When calling BSP_AUDIO_OUT_Pause() function for pause, only
bcostm 1:ee089790cdbb 282 * BSP_AUDIO_OUT_Resume() function should be called for resume (use of BSP_AUDIO_OUT_Play()
bcostm 1:ee089790cdbb 283 * function for resume could lead to unexpected behaviour).
bcostm 1:ee089790cdbb 284 * @retval AUDIO_OK if correct communication, else wrong communication
bcostm 1:ee089790cdbb 285 */
bcostm 1:ee089790cdbb 286 uint8_t BSP_AUDIO_OUT_Resume(void)
bcostm 1:ee089790cdbb 287 {
bcostm 1:ee089790cdbb 288 /* Call the Audio Codec Pause/Resume function */
bcostm 1:ee089790cdbb 289 if(audio_drv->Resume(AUDIO_I2C_ADDRESS) != 0)
bcostm 1:ee089790cdbb 290 {
bcostm 1:ee089790cdbb 291 return AUDIO_ERROR;
bcostm 1:ee089790cdbb 292 }
bcostm 1:ee089790cdbb 293 else
bcostm 1:ee089790cdbb 294 {
bcostm 1:ee089790cdbb 295 /* Call the Media layer pause/resume function */
bcostm 1:ee089790cdbb 296 HAL_SAI_DMAResume(&haudio_out_sai);
bcostm 1:ee089790cdbb 297
bcostm 1:ee089790cdbb 298 /* Return AUDIO_OK when all operations are correctly done */
bcostm 1:ee089790cdbb 299 return AUDIO_OK;
bcostm 1:ee089790cdbb 300 }
bcostm 1:ee089790cdbb 301 }
bcostm 1:ee089790cdbb 302
bcostm 1:ee089790cdbb 303 /**
bcostm 1:ee089790cdbb 304 * @brief Stops audio playing and Power down the Audio Codec.
bcostm 1:ee089790cdbb 305 * @param Option: could be one of the following parameters
bcostm 1:ee089790cdbb 306 * - CODEC_PDWN_SW: for software power off (by writing registers).
bcostm 1:ee089790cdbb 307 * Then no need to reconfigure the Codec after power on.
bcostm 1:ee089790cdbb 308 * - CODEC_PDWN_HW: completely shut down the codec (physically).
bcostm 1:ee089790cdbb 309 * Then need to reconfigure the Codec after power on.
bcostm 1:ee089790cdbb 310 * @retval AUDIO_OK if correct communication, else wrong communication
bcostm 1:ee089790cdbb 311 */
bcostm 1:ee089790cdbb 312 uint8_t BSP_AUDIO_OUT_Stop(uint32_t Option)
bcostm 1:ee089790cdbb 313 {
bcostm 1:ee089790cdbb 314 /* Call the Media layer stop function */
bcostm 1:ee089790cdbb 315 HAL_SAI_DMAStop(&haudio_out_sai);
bcostm 1:ee089790cdbb 316
bcostm 1:ee089790cdbb 317 /* Call Audio Codec Stop function */
bcostm 1:ee089790cdbb 318 if(audio_drv->Stop(AUDIO_I2C_ADDRESS, Option) != 0)
bcostm 1:ee089790cdbb 319 {
bcostm 1:ee089790cdbb 320 return AUDIO_ERROR;
bcostm 1:ee089790cdbb 321 }
bcostm 1:ee089790cdbb 322 else
bcostm 1:ee089790cdbb 323 {
bcostm 1:ee089790cdbb 324 if(Option == CODEC_PDWN_HW)
bcostm 1:ee089790cdbb 325 {
bcostm 1:ee089790cdbb 326 /* Wait at least 100us */
bcostm 1:ee089790cdbb 327 HAL_Delay(1);
bcostm 1:ee089790cdbb 328 }
bcostm 1:ee089790cdbb 329 /* Return AUDIO_OK when all operations are correctly done */
bcostm 1:ee089790cdbb 330 return AUDIO_OK;
bcostm 1:ee089790cdbb 331 }
bcostm 1:ee089790cdbb 332 }
bcostm 1:ee089790cdbb 333
bcostm 1:ee089790cdbb 334 /**
bcostm 1:ee089790cdbb 335 * @brief Controls the current audio volume level.
bcostm 1:ee089790cdbb 336 * @param Volume: Volume level to be set in percentage from 0% to 100% (0 for
bcostm 1:ee089790cdbb 337 * Mute and 100 for Max volume level).
bcostm 1:ee089790cdbb 338 * @retval AUDIO_OK if correct communication, else wrong communication
bcostm 1:ee089790cdbb 339 */
bcostm 1:ee089790cdbb 340 uint8_t BSP_AUDIO_OUT_SetVolume(uint8_t Volume)
bcostm 1:ee089790cdbb 341 {
bcostm 1:ee089790cdbb 342 /* Call the codec volume control function with converted volume value */
bcostm 1:ee089790cdbb 343 if(audio_drv->SetVolume(AUDIO_I2C_ADDRESS, Volume) != 0)
bcostm 1:ee089790cdbb 344 {
bcostm 1:ee089790cdbb 345 return AUDIO_ERROR;
bcostm 1:ee089790cdbb 346 }
bcostm 1:ee089790cdbb 347 else
bcostm 1:ee089790cdbb 348 {
bcostm 1:ee089790cdbb 349 /* Return AUDIO_OK when all operations are correctly done */
bcostm 1:ee089790cdbb 350 return AUDIO_OK;
bcostm 1:ee089790cdbb 351 }
bcostm 1:ee089790cdbb 352 }
bcostm 1:ee089790cdbb 353
bcostm 1:ee089790cdbb 354 /**
bcostm 1:ee089790cdbb 355 * @brief Enables or disables the MUTE mode by software
bcostm 1:ee089790cdbb 356 * @param Cmd: Could be AUDIO_MUTE_ON to mute sound or AUDIO_MUTE_OFF to
bcostm 1:ee089790cdbb 357 * unmute the codec and restore previous volume level.
bcostm 1:ee089790cdbb 358 * @retval AUDIO_OK if correct communication, else wrong communication
bcostm 1:ee089790cdbb 359 */
bcostm 1:ee089790cdbb 360 uint8_t BSP_AUDIO_OUT_SetMute(uint32_t Cmd)
bcostm 1:ee089790cdbb 361 {
bcostm 1:ee089790cdbb 362 /* Call the Codec Mute function */
bcostm 1:ee089790cdbb 363 if(audio_drv->SetMute(AUDIO_I2C_ADDRESS, Cmd) != 0)
bcostm 1:ee089790cdbb 364 {
bcostm 1:ee089790cdbb 365 return AUDIO_ERROR;
bcostm 1:ee089790cdbb 366 }
bcostm 1:ee089790cdbb 367 else
bcostm 1:ee089790cdbb 368 {
bcostm 1:ee089790cdbb 369 /* Return AUDIO_OK when all operations are correctly done */
bcostm 1:ee089790cdbb 370 return AUDIO_OK;
bcostm 1:ee089790cdbb 371 }
bcostm 1:ee089790cdbb 372 }
bcostm 1:ee089790cdbb 373
bcostm 1:ee089790cdbb 374 /**
bcostm 1:ee089790cdbb 375 * @brief Switch dynamically (while audio file is played) the output target
bcostm 1:ee089790cdbb 376 * (speaker or headphone).
bcostm 1:ee089790cdbb 377 * @param Output: The audio output target: OUTPUT_DEVICE_SPEAKER,
bcostm 1:ee089790cdbb 378 * OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH
bcostm 1:ee089790cdbb 379 * @retval AUDIO_OK if correct communication, else wrong communication
bcostm 1:ee089790cdbb 380 */
bcostm 1:ee089790cdbb 381 uint8_t BSP_AUDIO_OUT_SetOutputMode(uint8_t Output)
bcostm 1:ee089790cdbb 382 {
bcostm 1:ee089790cdbb 383 /* Call the Codec output device function */
bcostm 1:ee089790cdbb 384 if(audio_drv->SetOutputMode(AUDIO_I2C_ADDRESS, Output) != 0)
bcostm 1:ee089790cdbb 385 {
bcostm 1:ee089790cdbb 386 return AUDIO_ERROR;
bcostm 1:ee089790cdbb 387 }
bcostm 1:ee089790cdbb 388 else
bcostm 1:ee089790cdbb 389 {
bcostm 1:ee089790cdbb 390 /* Return AUDIO_OK when all operations are correctly done */
bcostm 1:ee089790cdbb 391 return AUDIO_OK;
bcostm 1:ee089790cdbb 392 }
bcostm 1:ee089790cdbb 393 }
bcostm 1:ee089790cdbb 394
bcostm 1:ee089790cdbb 395 /**
bcostm 1:ee089790cdbb 396 * @brief Updates the audio frequency.
bcostm 1:ee089790cdbb 397 * @param AudioFreq: Audio frequency used to play the audio stream.
bcostm 1:ee089790cdbb 398 * @note This API should be called after the BSP_AUDIO_OUT_Init() to adjust the
bcostm 1:ee089790cdbb 399 * audio frequency.
bcostm 1:ee089790cdbb 400 * @retval None
bcostm 1:ee089790cdbb 401 */
bcostm 1:ee089790cdbb 402 void BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq)
bcostm 1:ee089790cdbb 403 {
bcostm 1:ee089790cdbb 404 /* PLL clock is set depending by the AudioFreq (44.1khz vs 48khz groups) */
bcostm 1:ee089790cdbb 405 BSP_AUDIO_OUT_ClockConfig(&haudio_out_sai, AudioFreq, NULL);
bcostm 1:ee089790cdbb 406
bcostm 1:ee089790cdbb 407 /* Disable SAI peripheral to allow access to SAI internal registers */
bcostm 1:ee089790cdbb 408 __HAL_SAI_DISABLE(&haudio_out_sai);
bcostm 1:ee089790cdbb 409
bcostm 1:ee089790cdbb 410 /* Update the SAI audio frequency configuration */
bcostm 1:ee089790cdbb 411 haudio_out_sai.Init.AudioFrequency = AudioFreq;
bcostm 1:ee089790cdbb 412 HAL_SAI_Init(&haudio_out_sai);
bcostm 1:ee089790cdbb 413
bcostm 1:ee089790cdbb 414 /* Enable SAI peripheral to generate MCLK */
bcostm 1:ee089790cdbb 415 __HAL_SAI_ENABLE(&haudio_out_sai);
bcostm 1:ee089790cdbb 416 }
bcostm 1:ee089790cdbb 417
bcostm 1:ee089790cdbb 418 /**
bcostm 1:ee089790cdbb 419 * @brief Updates the Audio frame slot configuration.
bcostm 1:ee089790cdbb 420 * @param AudioFrameSlot: specifies the audio Frame slot
bcostm 1:ee089790cdbb 421 * This parameter can be one of the following values
bcostm 1:ee089790cdbb 422 * @arg CODEC_AUDIOFRAME_SLOT_0123
bcostm 1:ee089790cdbb 423 * @arg CODEC_AUDIOFRAME_SLOT_02
bcostm 1:ee089790cdbb 424 * @arg CODEC_AUDIOFRAME_SLOT_13
bcostm 1:ee089790cdbb 425 * @note This API should be called after the BSP_AUDIO_OUT_Init() to adjust the
bcostm 1:ee089790cdbb 426 * audio frame slot.
bcostm 1:ee089790cdbb 427 * @retval None
bcostm 1:ee089790cdbb 428 */
bcostm 1:ee089790cdbb 429 void BSP_AUDIO_OUT_SetAudioFrameSlot(uint32_t AudioFrameSlot)
bcostm 1:ee089790cdbb 430 {
bcostm 1:ee089790cdbb 431 /* Disable SAI peripheral to allow access to SAI internal registers */
bcostm 1:ee089790cdbb 432 __HAL_SAI_DISABLE(&haudio_out_sai);
bcostm 1:ee089790cdbb 433
bcostm 1:ee089790cdbb 434 /* Update the SAI audio frame slot configuration */
bcostm 1:ee089790cdbb 435 haudio_out_sai.SlotInit.SlotActive = AudioFrameSlot;
bcostm 1:ee089790cdbb 436 HAL_SAI_Init(&haudio_out_sai);
bcostm 1:ee089790cdbb 437
bcostm 1:ee089790cdbb 438 /* Enable SAI peripheral to generate MCLK */
bcostm 1:ee089790cdbb 439 __HAL_SAI_ENABLE(&haudio_out_sai);
bcostm 1:ee089790cdbb 440 }
bcostm 1:ee089790cdbb 441
bcostm 1:ee089790cdbb 442 /**
bcostm 1:ee089790cdbb 443 * @brief Deinit the audio peripherals.
bcostm 1:ee089790cdbb 444 * @retval None
bcostm 1:ee089790cdbb 445 */
bcostm 1:ee089790cdbb 446 void BSP_AUDIO_OUT_DeInit(void)
bcostm 1:ee089790cdbb 447 {
bcostm 1:ee089790cdbb 448 SAIx_Out_DeInit();
bcostm 1:ee089790cdbb 449 /* DeInit the SAI MSP : this __weak function can be rewritten by the application */
bcostm 1:ee089790cdbb 450 BSP_AUDIO_OUT_MspDeInit(&haudio_out_sai, NULL);
bcostm 1:ee089790cdbb 451 }
bcostm 1:ee089790cdbb 452
bcostm 1:ee089790cdbb 453 /**
bcostm 1:ee089790cdbb 454 * @brief Tx Transfer completed callbacks.
bcostm 1:ee089790cdbb 455 * @param hsai: SAI handle
bcostm 1:ee089790cdbb 456 * @retval None
bcostm 1:ee089790cdbb 457 */
bcostm 1:ee089790cdbb 458 void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
bcostm 1:ee089790cdbb 459 {
bcostm 1:ee089790cdbb 460 /* Manage the remaining file size and new address offset: This function
bcostm 1:ee089790cdbb 461 should be coded by user (its prototype is already declared in stm32746g_discovery_audio.h) */
bcostm 1:ee089790cdbb 462 BSP_AUDIO_OUT_TransferComplete_CallBack();
bcostm 1:ee089790cdbb 463 }
bcostm 1:ee089790cdbb 464
bcostm 1:ee089790cdbb 465 /**
bcostm 1:ee089790cdbb 466 * @brief Tx Half Transfer completed callbacks.
bcostm 1:ee089790cdbb 467 * @param hsai: SAI handle
bcostm 1:ee089790cdbb 468 * @retval None
bcostm 1:ee089790cdbb 469 */
bcostm 1:ee089790cdbb 470 void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
bcostm 1:ee089790cdbb 471 {
bcostm 1:ee089790cdbb 472 /* Manage the remaining file size and new address offset: This function
bcostm 1:ee089790cdbb 473 should be coded by user (its prototype is already declared in stm32746g_discovery_audio.h) */
bcostm 1:ee089790cdbb 474 BSP_AUDIO_OUT_HalfTransfer_CallBack();
bcostm 1:ee089790cdbb 475 }
bcostm 1:ee089790cdbb 476
bcostm 1:ee089790cdbb 477 /**
bcostm 1:ee089790cdbb 478 * @brief SAI error callbacks.
bcostm 1:ee089790cdbb 479 * @param hsai: SAI handle
bcostm 1:ee089790cdbb 480 * @retval None
bcostm 1:ee089790cdbb 481 */
bcostm 1:ee089790cdbb 482 void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai)
bcostm 1:ee089790cdbb 483 {
bcostm 1:ee089790cdbb 484 HAL_SAI_StateTypeDef audio_out_state;
bcostm 1:ee089790cdbb 485 HAL_SAI_StateTypeDef audio_in_state;
bcostm 1:ee089790cdbb 486
bcostm 1:ee089790cdbb 487 audio_out_state = HAL_SAI_GetState(&haudio_out_sai);
bcostm 1:ee089790cdbb 488 audio_in_state = HAL_SAI_GetState(&haudio_in_sai);
bcostm 1:ee089790cdbb 489
bcostm 1:ee089790cdbb 490 /* Determines if it is an audio out or audio in error */
bcostm 1:ee089790cdbb 491 if ((audio_out_state == HAL_SAI_STATE_BUSY) || (audio_out_state == HAL_SAI_STATE_BUSY_TX)
bcostm 1:ee089790cdbb 492 || (audio_out_state == HAL_SAI_STATE_TIMEOUT) || (audio_out_state == HAL_SAI_STATE_ERROR))
bcostm 1:ee089790cdbb 493 {
bcostm 1:ee089790cdbb 494 BSP_AUDIO_OUT_Error_CallBack();
bcostm 1:ee089790cdbb 495 }
bcostm 1:ee089790cdbb 496
bcostm 1:ee089790cdbb 497 if ((audio_in_state == HAL_SAI_STATE_BUSY) || (audio_in_state == HAL_SAI_STATE_BUSY_RX)
bcostm 1:ee089790cdbb 498 || (audio_in_state == HAL_SAI_STATE_TIMEOUT) || (audio_in_state == HAL_SAI_STATE_ERROR))
bcostm 1:ee089790cdbb 499 {
bcostm 1:ee089790cdbb 500 BSP_AUDIO_IN_Error_CallBack();
bcostm 1:ee089790cdbb 501 }
bcostm 1:ee089790cdbb 502 }
bcostm 1:ee089790cdbb 503
bcostm 1:ee089790cdbb 504 /**
bcostm 1:ee089790cdbb 505 * @brief Manages the DMA full Transfer complete event.
bcostm 1:ee089790cdbb 506 * @retval None
bcostm 1:ee089790cdbb 507 */
bcostm 1:ee089790cdbb 508 __weak void BSP_AUDIO_OUT_TransferComplete_CallBack(void)
bcostm 1:ee089790cdbb 509 {
bcostm 1:ee089790cdbb 510 }
bcostm 1:ee089790cdbb 511
bcostm 1:ee089790cdbb 512 /**
bcostm 1:ee089790cdbb 513 * @brief Manages the DMA Half Transfer complete event.
bcostm 1:ee089790cdbb 514 * @retval None
bcostm 1:ee089790cdbb 515 */
bcostm 1:ee089790cdbb 516 __weak void BSP_AUDIO_OUT_HalfTransfer_CallBack(void)
bcostm 1:ee089790cdbb 517 {
bcostm 1:ee089790cdbb 518 }
bcostm 1:ee089790cdbb 519
bcostm 1:ee089790cdbb 520 /**
bcostm 1:ee089790cdbb 521 * @brief Manages the DMA FIFO error event.
bcostm 1:ee089790cdbb 522 * @retval None
bcostm 1:ee089790cdbb 523 */
bcostm 1:ee089790cdbb 524 __weak void BSP_AUDIO_OUT_Error_CallBack(void)
bcostm 1:ee089790cdbb 525 {
bcostm 1:ee089790cdbb 526 }
bcostm 1:ee089790cdbb 527
bcostm 1:ee089790cdbb 528 /**
bcostm 1:ee089790cdbb 529 * @brief Initializes BSP_AUDIO_OUT MSP.
bcostm 1:ee089790cdbb 530 * @param hsai: SAI handle
bcostm 1:ee089790cdbb 531 * @param Params
bcostm 1:ee089790cdbb 532 * @retval None
bcostm 1:ee089790cdbb 533 */
bcostm 1:ee089790cdbb 534 __weak void BSP_AUDIO_OUT_MspInit(SAI_HandleTypeDef *hsai, void *Params)
bcostm 1:ee089790cdbb 535 {
bcostm 1:ee089790cdbb 536 static DMA_HandleTypeDef hdma_sai_tx;
bcostm 1:ee089790cdbb 537 GPIO_InitTypeDef gpio_init_structure;
bcostm 1:ee089790cdbb 538
bcostm 1:ee089790cdbb 539 /* Enable SAI clock */
bcostm 1:ee089790cdbb 540 AUDIO_OUT_SAIx_CLK_ENABLE();
bcostm 1:ee089790cdbb 541
bcostm 1:ee089790cdbb 542 /* Enable GPIO clock */
bcostm 1:ee089790cdbb 543 AUDIO_OUT_SAIx_MCLK_ENABLE();
bcostm 1:ee089790cdbb 544 AUDIO_OUT_SAIx_SCK_SD_ENABLE();
bcostm 1:ee089790cdbb 545 AUDIO_OUT_SAIx_FS_ENABLE();
bcostm 1:ee089790cdbb 546 /* CODEC_SAI pins configuration: FS, SCK, MCK and SD pins ------------------*/
bcostm 1:ee089790cdbb 547 gpio_init_structure.Pin = AUDIO_OUT_SAIx_FS_PIN;
bcostm 1:ee089790cdbb 548 gpio_init_structure.Mode = GPIO_MODE_AF_PP;
bcostm 1:ee089790cdbb 549 gpio_init_structure.Pull = GPIO_NOPULL;
bcostm 1:ee089790cdbb 550 gpio_init_structure.Speed = GPIO_SPEED_HIGH;
bcostm 1:ee089790cdbb 551 gpio_init_structure.Alternate = AUDIO_OUT_SAIx_FS_SD_MCLK_AF;
bcostm 1:ee089790cdbb 552 HAL_GPIO_Init(AUDIO_OUT_SAIx_FS_GPIO_PORT, &gpio_init_structure);
bcostm 1:ee089790cdbb 553
bcostm 1:ee089790cdbb 554 gpio_init_structure.Pin = AUDIO_OUT_SAIx_SCK_PIN;
bcostm 1:ee089790cdbb 555 gpio_init_structure.Mode = GPIO_MODE_AF_PP;
bcostm 1:ee089790cdbb 556 gpio_init_structure.Pull = GPIO_NOPULL;
bcostm 1:ee089790cdbb 557 gpio_init_structure.Speed = GPIO_SPEED_HIGH;
bcostm 1:ee089790cdbb 558 gpio_init_structure.Alternate = AUDIO_OUT_SAIx_SCK_AF;
bcostm 1:ee089790cdbb 559 HAL_GPIO_Init(AUDIO_OUT_SAIx_SCK_SD_GPIO_PORT, &gpio_init_structure);
bcostm 1:ee089790cdbb 560
bcostm 1:ee089790cdbb 561 gpio_init_structure.Pin = AUDIO_OUT_SAIx_SD_PIN;
bcostm 1:ee089790cdbb 562 gpio_init_structure.Mode = GPIO_MODE_AF_PP;
bcostm 1:ee089790cdbb 563 gpio_init_structure.Pull = GPIO_NOPULL;
bcostm 1:ee089790cdbb 564 gpio_init_structure.Speed = GPIO_SPEED_HIGH;
bcostm 1:ee089790cdbb 565 gpio_init_structure.Alternate = AUDIO_OUT_SAIx_FS_SD_MCLK_AF;
bcostm 1:ee089790cdbb 566 HAL_GPIO_Init(AUDIO_OUT_SAIx_SCK_SD_GPIO_PORT, &gpio_init_structure);
bcostm 1:ee089790cdbb 567
bcostm 1:ee089790cdbb 568 gpio_init_structure.Pin = AUDIO_OUT_SAIx_MCLK_PIN;
bcostm 1:ee089790cdbb 569 gpio_init_structure.Mode = GPIO_MODE_AF_PP;
bcostm 1:ee089790cdbb 570 gpio_init_structure.Pull = GPIO_NOPULL;
bcostm 1:ee089790cdbb 571 gpio_init_structure.Speed = GPIO_SPEED_HIGH;
bcostm 1:ee089790cdbb 572 gpio_init_structure.Alternate = AUDIO_OUT_SAIx_FS_SD_MCLK_AF;
bcostm 1:ee089790cdbb 573 HAL_GPIO_Init(AUDIO_OUT_SAIx_MCLK_GPIO_PORT, &gpio_init_structure);
bcostm 1:ee089790cdbb 574
bcostm 1:ee089790cdbb 575 /* Enable the DMA clock */
bcostm 1:ee089790cdbb 576 AUDIO_OUT_SAIx_DMAx_CLK_ENABLE();
bcostm 1:ee089790cdbb 577
bcostm 1:ee089790cdbb 578 if(hsai->Instance == AUDIO_OUT_SAIx)
bcostm 1:ee089790cdbb 579 {
bcostm 1:ee089790cdbb 580 /* Configure the hdma_saiTx handle parameters */
bcostm 1:ee089790cdbb 581 hdma_sai_tx.Init.Channel = AUDIO_OUT_SAIx_DMAx_CHANNEL;
bcostm 1:ee089790cdbb 582 hdma_sai_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
bcostm 1:ee089790cdbb 583 hdma_sai_tx.Init.PeriphInc = DMA_PINC_DISABLE;
bcostm 1:ee089790cdbb 584 hdma_sai_tx.Init.MemInc = DMA_MINC_ENABLE;
bcostm 1:ee089790cdbb 585 hdma_sai_tx.Init.PeriphDataAlignment = AUDIO_OUT_SAIx_DMAx_PERIPH_DATA_SIZE;
bcostm 1:ee089790cdbb 586 hdma_sai_tx.Init.MemDataAlignment = AUDIO_OUT_SAIx_DMAx_MEM_DATA_SIZE;
bcostm 1:ee089790cdbb 587 hdma_sai_tx.Init.Mode = DMA_CIRCULAR;
bcostm 1:ee089790cdbb 588 hdma_sai_tx.Init.Priority = DMA_PRIORITY_HIGH;
bcostm 1:ee089790cdbb 589 hdma_sai_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
bcostm 1:ee089790cdbb 590 hdma_sai_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
bcostm 1:ee089790cdbb 591 hdma_sai_tx.Init.MemBurst = DMA_MBURST_SINGLE;
bcostm 1:ee089790cdbb 592 hdma_sai_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
bcostm 1:ee089790cdbb 593
bcostm 1:ee089790cdbb 594 hdma_sai_tx.Instance = AUDIO_OUT_SAIx_DMAx_STREAM;
bcostm 1:ee089790cdbb 595
bcostm 1:ee089790cdbb 596 /* Associate the DMA handle */
bcostm 1:ee089790cdbb 597 __HAL_LINKDMA(hsai, hdmatx, hdma_sai_tx);
bcostm 1:ee089790cdbb 598
bcostm 1:ee089790cdbb 599 /* Deinitialize the Stream for new transfer */
bcostm 1:ee089790cdbb 600 HAL_DMA_DeInit(&hdma_sai_tx);
bcostm 1:ee089790cdbb 601
bcostm 1:ee089790cdbb 602 /* Configure the DMA Stream */
bcostm 1:ee089790cdbb 603 HAL_DMA_Init(&hdma_sai_tx);
bcostm 1:ee089790cdbb 604 }
adustm 2:458ab1edf6b2 605 #if ( __MBED__ == 1)
adustm 2:458ab1edf6b2 606 // Enable interrupt
adustm 2:458ab1edf6b2 607 IRQn_Type irqn = (IRQn_Type)(AUDIO_OUT_SAIx_DMAx_IRQ);
adustm 2:458ab1edf6b2 608 NVIC_ClearPendingIRQ(irqn);
adustm 2:458ab1edf6b2 609 NVIC_DisableIRQ(irqn);
adustm 2:458ab1edf6b2 610 NVIC_SetPriority(irqn, AUDIO_OUT_IRQ_PREPRIO);
adustm 2:458ab1edf6b2 611 NVIC_SetVector(irqn, (uint32_t)AUDIO_OUT_SAIx_DMAx_IRQHandler);
adustm 2:458ab1edf6b2 612 NVIC_EnableIRQ(irqn);
adustm 2:458ab1edf6b2 613
adustm 2:458ab1edf6b2 614 #else
bcostm 1:ee089790cdbb 615 /* SAI DMA IRQ Channel configuration */
bcostm 1:ee089790cdbb 616 HAL_NVIC_SetPriority(AUDIO_OUT_SAIx_DMAx_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0);
bcostm 1:ee089790cdbb 617 HAL_NVIC_EnableIRQ(AUDIO_OUT_SAIx_DMAx_IRQ);
adustm 2:458ab1edf6b2 618 #endif
bcostm 1:ee089790cdbb 619 }
bcostm 1:ee089790cdbb 620
bcostm 1:ee089790cdbb 621 /**
bcostm 1:ee089790cdbb 622 * @brief Deinitializes SAI MSP.
bcostm 1:ee089790cdbb 623 * @param hsai: SAI handle
bcostm 1:ee089790cdbb 624 * @param Params
bcostm 1:ee089790cdbb 625 * @retval None
bcostm 1:ee089790cdbb 626 */
bcostm 1:ee089790cdbb 627 __weak void BSP_AUDIO_OUT_MspDeInit(SAI_HandleTypeDef *hsai, void *Params)
bcostm 1:ee089790cdbb 628 {
bcostm 1:ee089790cdbb 629 GPIO_InitTypeDef gpio_init_structure;
bcostm 1:ee089790cdbb 630
bcostm 1:ee089790cdbb 631 /* SAI DMA IRQ Channel deactivation */
bcostm 1:ee089790cdbb 632 HAL_NVIC_DisableIRQ(AUDIO_OUT_SAIx_DMAx_IRQ);
bcostm 1:ee089790cdbb 633
bcostm 1:ee089790cdbb 634 if(hsai->Instance == AUDIO_OUT_SAIx)
bcostm 1:ee089790cdbb 635 {
bcostm 1:ee089790cdbb 636 /* Deinitialize the DMA stream */
bcostm 1:ee089790cdbb 637 HAL_DMA_DeInit(hsai->hdmatx);
bcostm 1:ee089790cdbb 638 }
bcostm 1:ee089790cdbb 639
bcostm 1:ee089790cdbb 640 /* Disable SAI peripheral */
bcostm 1:ee089790cdbb 641 __HAL_SAI_DISABLE(hsai);
bcostm 1:ee089790cdbb 642
bcostm 1:ee089790cdbb 643 /* Deactives CODEC_SAI pins FS, SCK, MCK and SD by putting them in input mode */
bcostm 1:ee089790cdbb 644 gpio_init_structure.Pin = AUDIO_OUT_SAIx_FS_PIN;
bcostm 1:ee089790cdbb 645 HAL_GPIO_DeInit(AUDIO_OUT_SAIx_FS_GPIO_PORT, gpio_init_structure.Pin);
bcostm 1:ee089790cdbb 646
bcostm 1:ee089790cdbb 647 gpio_init_structure.Pin = AUDIO_OUT_SAIx_SCK_PIN;
bcostm 1:ee089790cdbb 648 HAL_GPIO_DeInit(AUDIO_OUT_SAIx_SCK_SD_GPIO_PORT, gpio_init_structure.Pin);
bcostm 1:ee089790cdbb 649
bcostm 1:ee089790cdbb 650 gpio_init_structure.Pin = AUDIO_OUT_SAIx_SD_PIN;
bcostm 1:ee089790cdbb 651 HAL_GPIO_DeInit(AUDIO_OUT_SAIx_SCK_SD_GPIO_PORT, gpio_init_structure.Pin);
bcostm 1:ee089790cdbb 652
bcostm 1:ee089790cdbb 653 gpio_init_structure.Pin = AUDIO_OUT_SAIx_MCLK_PIN;
bcostm 1:ee089790cdbb 654 HAL_GPIO_DeInit(AUDIO_OUT_SAIx_MCLK_GPIO_PORT, gpio_init_structure.Pin);
bcostm 1:ee089790cdbb 655
bcostm 1:ee089790cdbb 656 /* Disable SAI clock */
bcostm 1:ee089790cdbb 657 AUDIO_OUT_SAIx_CLK_DISABLE();
bcostm 1:ee089790cdbb 658
bcostm 1:ee089790cdbb 659 /* GPIO pins clock and DMA clock can be shut down in the application
bcostm 1:ee089790cdbb 660 by surcharging this __weak function */
bcostm 1:ee089790cdbb 661 }
bcostm 1:ee089790cdbb 662
bcostm 1:ee089790cdbb 663 /**
bcostm 1:ee089790cdbb 664 * @brief Clock Config.
bcostm 1:ee089790cdbb 665 * @param hsai: might be required to set audio peripheral predivider if any.
bcostm 1:ee089790cdbb 666 * @param AudioFreq: Audio frequency used to play the audio stream.
bcostm 1:ee089790cdbb 667 * @param Params
bcostm 1:ee089790cdbb 668 * @note This API is called by BSP_AUDIO_OUT_Init() and BSP_AUDIO_OUT_SetFrequency()
bcostm 1:ee089790cdbb 669 * Being __weak it can be overwritten by the application
bcostm 1:ee089790cdbb 670 * @retval None
bcostm 1:ee089790cdbb 671 */
bcostm 1:ee089790cdbb 672 __weak void BSP_AUDIO_OUT_ClockConfig(SAI_HandleTypeDef *hsai, uint32_t AudioFreq, void *Params)
bcostm 1:ee089790cdbb 673 {
bcostm 1:ee089790cdbb 674 RCC_PeriphCLKInitTypeDef rcc_ex_clk_init_struct;
bcostm 1:ee089790cdbb 675
bcostm 1:ee089790cdbb 676 HAL_RCCEx_GetPeriphCLKConfig(&rcc_ex_clk_init_struct);
bcostm 1:ee089790cdbb 677
bcostm 1:ee089790cdbb 678 /* Set the PLL configuration according to the audio frequency */
bcostm 1:ee089790cdbb 679 if((AudioFreq == AUDIO_FREQUENCY_11K) || (AudioFreq == AUDIO_FREQUENCY_22K) || (AudioFreq == AUDIO_FREQUENCY_44K))
bcostm 1:ee089790cdbb 680 {
bcostm 1:ee089790cdbb 681 /* Configure PLLI2S prescalers */
bcostm 1:ee089790cdbb 682 /* PLLI2S_VCO: VCO_429M
bcostm 1:ee089790cdbb 683 I2S_CLK(first level) = PLLI2S_VCO/PLLI2SQ = 429/2 = 214.5 Mhz
bcostm 1:ee089790cdbb 684 I2S_CLK_x = I2S_CLK(first level)/PLLI2SDIVQ = 214.5/19 = 11.289 Mhz */
bcostm 1:ee089790cdbb 685 rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI2;
bcostm 1:ee089790cdbb 686 rcc_ex_clk_init_struct.Sai2ClockSelection = RCC_SAI2CLKSOURCE_PLLI2S;
bcostm 1:ee089790cdbb 687 rcc_ex_clk_init_struct.PLLI2S.PLLI2SN = 429;
bcostm 1:ee089790cdbb 688 rcc_ex_clk_init_struct.PLLI2S.PLLI2SQ = 2;
bcostm 1:ee089790cdbb 689 rcc_ex_clk_init_struct.PLLI2SDivQ = 19;
bcostm 1:ee089790cdbb 690
bcostm 1:ee089790cdbb 691 HAL_RCCEx_PeriphCLKConfig(&rcc_ex_clk_init_struct);
bcostm 1:ee089790cdbb 692
bcostm 1:ee089790cdbb 693 }
bcostm 1:ee089790cdbb 694 else /* AUDIO_FREQUENCY_8K, AUDIO_FREQUENCY_16K, AUDIO_FREQUENCY_48K), AUDIO_FREQUENCY_96K */
bcostm 1:ee089790cdbb 695 {
bcostm 1:ee089790cdbb 696 /* I2S clock config
bcostm 1:ee089790cdbb 697 PLLI2S_VCO: VCO_344M
bcostm 1:ee089790cdbb 698 I2S_CLK(first level) = PLLI2S_VCO/PLLI2SQ = 344/7 = 49.142 Mhz
bcostm 1:ee089790cdbb 699 I2S_CLK_x = I2S_CLK(first level)/PLLI2SDIVQ = 49.142/1 = 49.142 Mhz */
bcostm 1:ee089790cdbb 700 rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI2;
bcostm 1:ee089790cdbb 701 rcc_ex_clk_init_struct.Sai2ClockSelection = RCC_SAI2CLKSOURCE_PLLI2S;
bcostm 1:ee089790cdbb 702 rcc_ex_clk_init_struct.PLLI2S.PLLI2SN = 344;
bcostm 1:ee089790cdbb 703 rcc_ex_clk_init_struct.PLLI2S.PLLI2SQ = 7;
bcostm 1:ee089790cdbb 704 rcc_ex_clk_init_struct.PLLI2SDivQ = 1;
bcostm 1:ee089790cdbb 705
bcostm 1:ee089790cdbb 706 HAL_RCCEx_PeriphCLKConfig(&rcc_ex_clk_init_struct);
bcostm 1:ee089790cdbb 707 }
bcostm 1:ee089790cdbb 708 }
bcostm 1:ee089790cdbb 709
bcostm 1:ee089790cdbb 710 /*******************************************************************************
bcostm 1:ee089790cdbb 711 Static Functions
bcostm 1:ee089790cdbb 712 *******************************************************************************/
bcostm 1:ee089790cdbb 713
bcostm 1:ee089790cdbb 714 /**
bcostm 1:ee089790cdbb 715 * @brief Initializes the output Audio Codec audio interface (SAI).
bcostm 1:ee089790cdbb 716 * @param AudioFreq: Audio frequency to be configured for the SAI peripheral.
bcostm 1:ee089790cdbb 717 * @note The default SlotActive configuration is set to CODEC_AUDIOFRAME_SLOT_0123
bcostm 1:ee089790cdbb 718 * and user can update this configuration using
bcostm 1:ee089790cdbb 719 * @retval None
bcostm 1:ee089790cdbb 720 */
bcostm 1:ee089790cdbb 721 static void SAIx_Out_Init(uint32_t AudioFreq)
bcostm 1:ee089790cdbb 722 {
bcostm 1:ee089790cdbb 723 /* Initialize the haudio_out_sai Instance parameter */
bcostm 1:ee089790cdbb 724 haudio_out_sai.Instance = AUDIO_OUT_SAIx;
bcostm 1:ee089790cdbb 725
bcostm 1:ee089790cdbb 726 /* Disable SAI peripheral to allow access to SAI internal registers */
bcostm 1:ee089790cdbb 727 __HAL_SAI_DISABLE(&haudio_out_sai);
bcostm 1:ee089790cdbb 728
bcostm 1:ee089790cdbb 729 /* Configure SAI_Block_x
bcostm 1:ee089790cdbb 730 LSBFirst: Disabled
bcostm 1:ee089790cdbb 731 DataSize: 16 */
bcostm 1:ee089790cdbb 732 haudio_out_sai.Init.AudioFrequency = AudioFreq;
bcostm 1:ee089790cdbb 733 haudio_out_sai.Init.AudioMode = SAI_MODEMASTER_TX;
bcostm 1:ee089790cdbb 734 haudio_out_sai.Init.NoDivider = SAI_MASTERDIVIDER_ENABLED;
bcostm 1:ee089790cdbb 735 haudio_out_sai.Init.Protocol = SAI_FREE_PROTOCOL;
bcostm 1:ee089790cdbb 736 haudio_out_sai.Init.DataSize = SAI_DATASIZE_16;
bcostm 1:ee089790cdbb 737 haudio_out_sai.Init.FirstBit = SAI_FIRSTBIT_MSB;
bcostm 1:ee089790cdbb 738 haudio_out_sai.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
bcostm 1:ee089790cdbb 739 haudio_out_sai.Init.Synchro = SAI_ASYNCHRONOUS;
bcostm 1:ee089790cdbb 740 haudio_out_sai.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLED;
bcostm 1:ee089790cdbb 741 haudio_out_sai.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
bcostm 1:ee089790cdbb 742
bcostm 1:ee089790cdbb 743 /* Configure SAI_Block_x Frame
bcostm 1:ee089790cdbb 744 Frame Length: 64
bcostm 1:ee089790cdbb 745 Frame active Length: 32
bcostm 1:ee089790cdbb 746 FS Definition: Start frame + Channel Side identification
bcostm 1:ee089790cdbb 747 FS Polarity: FS active Low
bcostm 1:ee089790cdbb 748 FS Offset: FS asserted one bit before the first bit of slot 0 */
bcostm 1:ee089790cdbb 749 haudio_out_sai.FrameInit.FrameLength = 64;
bcostm 1:ee089790cdbb 750 haudio_out_sai.FrameInit.ActiveFrameLength = 32;
bcostm 1:ee089790cdbb 751 haudio_out_sai.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
bcostm 1:ee089790cdbb 752 haudio_out_sai.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
bcostm 1:ee089790cdbb 753 haudio_out_sai.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
bcostm 1:ee089790cdbb 754
bcostm 1:ee089790cdbb 755 /* Configure SAI Block_x Slot
bcostm 1:ee089790cdbb 756 Slot First Bit Offset: 0
bcostm 1:ee089790cdbb 757 Slot Size : 16
bcostm 1:ee089790cdbb 758 Slot Number: 4
bcostm 1:ee089790cdbb 759 Slot Active: All slot actives */
bcostm 1:ee089790cdbb 760 haudio_out_sai.SlotInit.FirstBitOffset = 0;
bcostm 1:ee089790cdbb 761 haudio_out_sai.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
bcostm 1:ee089790cdbb 762 haudio_out_sai.SlotInit.SlotNumber = 4;
bcostm 1:ee089790cdbb 763 haudio_out_sai.SlotInit.SlotActive = CODEC_AUDIOFRAME_SLOT_0123;
bcostm 1:ee089790cdbb 764
bcostm 1:ee089790cdbb 765 HAL_SAI_Init(&haudio_out_sai);
bcostm 1:ee089790cdbb 766
bcostm 1:ee089790cdbb 767 /* Enable SAI peripheral to generate MCLK */
bcostm 1:ee089790cdbb 768 __HAL_SAI_ENABLE(&haudio_out_sai);
bcostm 1:ee089790cdbb 769 }
bcostm 1:ee089790cdbb 770
bcostm 1:ee089790cdbb 771
bcostm 1:ee089790cdbb 772
bcostm 1:ee089790cdbb 773 /**
bcostm 1:ee089790cdbb 774 * @brief Deinitializes the output Audio Codec audio interface (SAI).
bcostm 1:ee089790cdbb 775 * @retval None
bcostm 1:ee089790cdbb 776 */
bcostm 1:ee089790cdbb 777 static void SAIx_Out_DeInit(void)
bcostm 1:ee089790cdbb 778 {
bcostm 1:ee089790cdbb 779 /* Initialize the haudio_out_sai Instance parameter */
bcostm 1:ee089790cdbb 780 haudio_out_sai.Instance = AUDIO_OUT_SAIx;
bcostm 1:ee089790cdbb 781
bcostm 1:ee089790cdbb 782 /* Disable SAI peripheral */
bcostm 1:ee089790cdbb 783 __HAL_SAI_DISABLE(&haudio_out_sai);
bcostm 1:ee089790cdbb 784
bcostm 1:ee089790cdbb 785 HAL_SAI_DeInit(&haudio_out_sai);
bcostm 1:ee089790cdbb 786 }
bcostm 1:ee089790cdbb 787
bcostm 1:ee089790cdbb 788 /**
bcostm 1:ee089790cdbb 789 * @}
bcostm 1:ee089790cdbb 790 */
bcostm 1:ee089790cdbb 791
bcostm 1:ee089790cdbb 792 /** @defgroup STM32746G_DISCOVERY_AUDIO_Out_Private_Functions STM32746G_DISCOVERY_AUDIO Out Private Functions
bcostm 1:ee089790cdbb 793 * @{
bcostm 1:ee089790cdbb 794 */
bcostm 1:ee089790cdbb 795
bcostm 1:ee089790cdbb 796 /**
bcostm 1:ee089790cdbb 797 * @brief Initializes wave recording.
bcostm 1:ee089790cdbb 798 * @param InputDevice: INPUT_DEVICE_DIGITAL_MICROPHONE_2 or INPUT_DEVICE_INPUT_LINE_1
bcostm 1:ee089790cdbb 799 * @param Volume: Initial volume level (in range 0(Mute)..80(+0dB)..100(+17.625dB))
bcostm 1:ee089790cdbb 800 * @param AudioFreq: Audio frequency to be configured for the SAI peripheral.
bcostm 1:ee089790cdbb 801 * @retval AUDIO_OK if correct communication, else wrong communication
bcostm 1:ee089790cdbb 802 */
bcostm 1:ee089790cdbb 803 uint8_t BSP_AUDIO_IN_Init(uint16_t InputDevice, uint8_t Volume, uint32_t AudioFreq)
bcostm 1:ee089790cdbb 804 {
bcostm 1:ee089790cdbb 805 uint8_t ret = AUDIO_ERROR;
bcostm 1:ee089790cdbb 806 uint32_t deviceid = 0x00;
bcostm 1:ee089790cdbb 807 uint32_t slot_active;
bcostm 1:ee089790cdbb 808
bcostm 1:ee089790cdbb 809 if ((InputDevice != INPUT_DEVICE_INPUT_LINE_1) && /* Only INPUT_LINE_1 and MICROPHONE_2 inputs supported */
bcostm 1:ee089790cdbb 810 (InputDevice != INPUT_DEVICE_DIGITAL_MICROPHONE_2))
bcostm 1:ee089790cdbb 811 {
bcostm 1:ee089790cdbb 812 ret = AUDIO_ERROR;
bcostm 1:ee089790cdbb 813 }
bcostm 1:ee089790cdbb 814 else
bcostm 1:ee089790cdbb 815 {
bcostm 1:ee089790cdbb 816 /* Disable SAI */
bcostm 1:ee089790cdbb 817 SAIx_In_DeInit();
bcostm 1:ee089790cdbb 818
bcostm 1:ee089790cdbb 819 /* PLL clock is set depending on the AudioFreq (44.1khz vs 48khz groups) */
bcostm 1:ee089790cdbb 820 BSP_AUDIO_OUT_ClockConfig(&haudio_in_sai, AudioFreq, NULL); /* Clock config is shared between AUDIO IN and OUT */
bcostm 1:ee089790cdbb 821
bcostm 1:ee089790cdbb 822 /* SAI data transfer preparation:
bcostm 1:ee089790cdbb 823 Prepare the Media to be used for the audio transfer from SAI peripheral to memory */
bcostm 1:ee089790cdbb 824 haudio_in_sai.Instance = AUDIO_IN_SAIx;
bcostm 1:ee089790cdbb 825 if(HAL_SAI_GetState(&haudio_in_sai) == HAL_SAI_STATE_RESET)
bcostm 1:ee089790cdbb 826 {
bcostm 1:ee089790cdbb 827 /* Init the SAI MSP: this __weak function can be redefined by the application*/
bcostm 1:ee089790cdbb 828 BSP_AUDIO_OUT_MspInit(&haudio_in_sai, NULL); /* Initialize GPIOs for SAI2 block A Master signals */
bcostm 1:ee089790cdbb 829 BSP_AUDIO_IN_MspInit(&haudio_in_sai, NULL);
bcostm 1:ee089790cdbb 830 }
bcostm 1:ee089790cdbb 831
bcostm 1:ee089790cdbb 832 /* Configure SAI in master RX mode :
bcostm 1:ee089790cdbb 833 * - SAI2_block_A in master RX mode
bcostm 1:ee089790cdbb 834 * - SAI2_block_B in slave RX mode synchronous from SAI2_block_A
bcostm 1:ee089790cdbb 835 */
bcostm 1:ee089790cdbb 836 if (InputDevice == INPUT_DEVICE_DIGITAL_MICROPHONE_2)
bcostm 1:ee089790cdbb 837 {
bcostm 1:ee089790cdbb 838 slot_active = CODEC_AUDIOFRAME_SLOT_13;
bcostm 1:ee089790cdbb 839 }
bcostm 1:ee089790cdbb 840 else
bcostm 1:ee089790cdbb 841 {
bcostm 1:ee089790cdbb 842 slot_active = CODEC_AUDIOFRAME_SLOT_02;
bcostm 1:ee089790cdbb 843 }
bcostm 1:ee089790cdbb 844 SAIx_In_Init(SAI_MODEMASTER_RX, slot_active, AudioFreq);
bcostm 1:ee089790cdbb 845
bcostm 1:ee089790cdbb 846 /* wm8994 codec initialization */
bcostm 1:ee089790cdbb 847 deviceid = wm8994_drv.ReadID(AUDIO_I2C_ADDRESS);
bcostm 1:ee089790cdbb 848
bcostm 1:ee089790cdbb 849 if((deviceid) == WM8994_ID)
bcostm 1:ee089790cdbb 850 {
bcostm 1:ee089790cdbb 851 /* Reset the Codec Registers */
bcostm 1:ee089790cdbb 852 wm8994_drv.Reset(AUDIO_I2C_ADDRESS);
bcostm 1:ee089790cdbb 853 /* Initialize the audio driver structure */
bcostm 1:ee089790cdbb 854 audio_drv = &wm8994_drv;
bcostm 1:ee089790cdbb 855 ret = AUDIO_OK;
bcostm 1:ee089790cdbb 856 }
bcostm 1:ee089790cdbb 857 else
bcostm 1:ee089790cdbb 858 {
bcostm 1:ee089790cdbb 859 ret = AUDIO_ERROR;
bcostm 1:ee089790cdbb 860 }
bcostm 1:ee089790cdbb 861
bcostm 1:ee089790cdbb 862 if(ret == AUDIO_OK)
bcostm 1:ee089790cdbb 863 {
bcostm 1:ee089790cdbb 864 /* Initialize the codec internal registers */
bcostm 1:ee089790cdbb 865 audio_drv->Init(AUDIO_I2C_ADDRESS, InputDevice, Volume, AudioFreq);
bcostm 1:ee089790cdbb 866 }
bcostm 1:ee089790cdbb 867 }
bcostm 1:ee089790cdbb 868 return ret;
bcostm 1:ee089790cdbb 869 }
bcostm 1:ee089790cdbb 870
bcostm 1:ee089790cdbb 871 /**
bcostm 1:ee089790cdbb 872 * @brief Initializes wave recording and playback in parallel.
bcostm 1:ee089790cdbb 873 * @param InputDevice: INPUT_DEVICE_DIGITAL_MICROPHONE_2
bcostm 1:ee089790cdbb 874 * @param OutputDevice: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
bcostm 1:ee089790cdbb 875 * or OUTPUT_DEVICE_BOTH.
bcostm 1:ee089790cdbb 876 * @param Volume: Initial volume level (in range 0(Mute)..80(+0dB)..100(+17.625dB))
bcostm 1:ee089790cdbb 877 * @param AudioFreq: Audio frequency to be configured for the SAI peripheral.
bcostm 1:ee089790cdbb 878 * @retval AUDIO_OK if correct communication, else wrong communication
bcostm 1:ee089790cdbb 879 */
bcostm 1:ee089790cdbb 880 uint8_t BSP_AUDIO_IN_OUT_Init(uint16_t InputDevice, uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq)
bcostm 1:ee089790cdbb 881 {
bcostm 1:ee089790cdbb 882 uint8_t ret = AUDIO_ERROR;
bcostm 1:ee089790cdbb 883 uint32_t deviceid = 0x00;
bcostm 1:ee089790cdbb 884 uint32_t slot_active;
bcostm 1:ee089790cdbb 885
bcostm 1:ee089790cdbb 886 if (InputDevice != INPUT_DEVICE_DIGITAL_MICROPHONE_2) /* Only MICROPHONE_2 input supported */
bcostm 1:ee089790cdbb 887 {
bcostm 1:ee089790cdbb 888 ret = AUDIO_ERROR;
bcostm 1:ee089790cdbb 889 }
bcostm 1:ee089790cdbb 890 else
bcostm 1:ee089790cdbb 891 {
bcostm 1:ee089790cdbb 892 /* Disable SAI */
bcostm 1:ee089790cdbb 893 SAIx_In_DeInit();
bcostm 1:ee089790cdbb 894 SAIx_Out_DeInit();
bcostm 1:ee089790cdbb 895
bcostm 1:ee089790cdbb 896 /* PLL clock is set depending on the AudioFreq (44.1khz vs 48khz groups) */
bcostm 1:ee089790cdbb 897 BSP_AUDIO_OUT_ClockConfig(&haudio_in_sai, AudioFreq, NULL); /* Clock config is shared between AUDIO IN and OUT */
bcostm 1:ee089790cdbb 898
bcostm 1:ee089790cdbb 899 /* SAI data transfer preparation:
bcostm 1:ee089790cdbb 900 Prepare the Media to be used for the audio transfer from SAI peripheral to memory */
bcostm 1:ee089790cdbb 901 haudio_in_sai.Instance = AUDIO_IN_SAIx;
bcostm 1:ee089790cdbb 902 if(HAL_SAI_GetState(&haudio_in_sai) == HAL_SAI_STATE_RESET)
bcostm 1:ee089790cdbb 903 {
bcostm 1:ee089790cdbb 904 /* Init the SAI MSP: this __weak function can be redefined by the application*/
bcostm 1:ee089790cdbb 905 BSP_AUDIO_IN_MspInit(&haudio_in_sai, NULL);
bcostm 1:ee089790cdbb 906 }
bcostm 1:ee089790cdbb 907
bcostm 1:ee089790cdbb 908 /* SAI data transfer preparation:
bcostm 1:ee089790cdbb 909 Prepare the Media to be used for the audio transfer from memory to SAI peripheral */
bcostm 1:ee089790cdbb 910 haudio_out_sai.Instance = AUDIO_OUT_SAIx;
bcostm 1:ee089790cdbb 911 if(HAL_SAI_GetState(&haudio_out_sai) == HAL_SAI_STATE_RESET)
bcostm 1:ee089790cdbb 912 {
bcostm 1:ee089790cdbb 913 /* Init the SAI MSP: this __weak function can be redefined by the application*/
bcostm 1:ee089790cdbb 914 BSP_AUDIO_OUT_MspInit(&haudio_out_sai, NULL);
bcostm 1:ee089790cdbb 915 }
bcostm 1:ee089790cdbb 916
bcostm 1:ee089790cdbb 917 /* Configure SAI in master mode :
bcostm 1:ee089790cdbb 918 * - SAI2_block_A in master TX mode
bcostm 1:ee089790cdbb 919 * - SAI2_block_B in slave RX mode synchronous from SAI2_block_A
bcostm 1:ee089790cdbb 920 */
bcostm 1:ee089790cdbb 921 if (InputDevice == INPUT_DEVICE_DIGITAL_MICROPHONE_2)
bcostm 1:ee089790cdbb 922 {
bcostm 1:ee089790cdbb 923 slot_active = CODEC_AUDIOFRAME_SLOT_13;
bcostm 1:ee089790cdbb 924 }
bcostm 1:ee089790cdbb 925 else
bcostm 1:ee089790cdbb 926 {
bcostm 1:ee089790cdbb 927 slot_active = CODEC_AUDIOFRAME_SLOT_02;
bcostm 1:ee089790cdbb 928 }
bcostm 1:ee089790cdbb 929 SAIx_In_Init(SAI_MODEMASTER_TX, slot_active, AudioFreq);
bcostm 1:ee089790cdbb 930
bcostm 1:ee089790cdbb 931 /* wm8994 codec initialization */
bcostm 1:ee089790cdbb 932 deviceid = wm8994_drv.ReadID(AUDIO_I2C_ADDRESS);
bcostm 1:ee089790cdbb 933
bcostm 1:ee089790cdbb 934 if((deviceid) == WM8994_ID)
bcostm 1:ee089790cdbb 935 {
bcostm 1:ee089790cdbb 936 /* Reset the Codec Registers */
bcostm 1:ee089790cdbb 937 wm8994_drv.Reset(AUDIO_I2C_ADDRESS);
bcostm 1:ee089790cdbb 938 /* Initialize the audio driver structure */
bcostm 1:ee089790cdbb 939 audio_drv = &wm8994_drv;
bcostm 1:ee089790cdbb 940 ret = AUDIO_OK;
bcostm 1:ee089790cdbb 941 }
bcostm 1:ee089790cdbb 942 else
bcostm 1:ee089790cdbb 943 {
bcostm 1:ee089790cdbb 944 ret = AUDIO_ERROR;
bcostm 1:ee089790cdbb 945 }
bcostm 1:ee089790cdbb 946
bcostm 1:ee089790cdbb 947 if(ret == AUDIO_OK)
bcostm 1:ee089790cdbb 948 {
bcostm 1:ee089790cdbb 949 /* Initialize the codec internal registers */
bcostm 1:ee089790cdbb 950 audio_drv->Init(AUDIO_I2C_ADDRESS, InputDevice | OutputDevice, Volume, AudioFreq);
bcostm 1:ee089790cdbb 951 }
bcostm 1:ee089790cdbb 952 }
bcostm 1:ee089790cdbb 953 return ret;
bcostm 1:ee089790cdbb 954 }
bcostm 1:ee089790cdbb 955
bcostm 1:ee089790cdbb 956
bcostm 1:ee089790cdbb 957 /**
bcostm 1:ee089790cdbb 958 * @brief Starts audio recording.
bcostm 1:ee089790cdbb 959 * @param pbuf: Main buffer pointer for the recorded data storing
bcostm 1:ee089790cdbb 960 * @param size: size of the recorded buffer in number of elements (typically number of half-words)
bcostm 1:ee089790cdbb 961 * Be careful that it is not the same unit than BSP_AUDIO_OUT_Play function
bcostm 1:ee089790cdbb 962 * @retval AUDIO_OK if correct communication, else wrong communication
bcostm 1:ee089790cdbb 963 */
bcostm 1:ee089790cdbb 964 uint8_t BSP_AUDIO_IN_Record(uint16_t* pbuf, uint32_t size)
bcostm 1:ee089790cdbb 965 {
bcostm 1:ee089790cdbb 966 uint32_t ret = AUDIO_ERROR;
bcostm 1:ee089790cdbb 967
bcostm 1:ee089790cdbb 968 /* Start the process receive DMA */
bcostm 1:ee089790cdbb 969 HAL_SAI_Receive_DMA(&haudio_in_sai, (uint8_t*)pbuf, size);
bcostm 1:ee089790cdbb 970
bcostm 1:ee089790cdbb 971 /* Return AUDIO_OK when all operations are correctly done */
bcostm 1:ee089790cdbb 972 ret = AUDIO_OK;
bcostm 1:ee089790cdbb 973
bcostm 1:ee089790cdbb 974 return ret;
bcostm 1:ee089790cdbb 975 }
bcostm 1:ee089790cdbb 976
bcostm 1:ee089790cdbb 977 /**
bcostm 1:ee089790cdbb 978 * @brief Stops audio recording.
bcostm 1:ee089790cdbb 979 * @param Option: could be one of the following parameters
bcostm 1:ee089790cdbb 980 * - CODEC_PDWN_SW: for software power off (by writing registers).
bcostm 1:ee089790cdbb 981 * Then no need to reconfigure the Codec after power on.
bcostm 1:ee089790cdbb 982 * - CODEC_PDWN_HW: completely shut down the codec (physically).
bcostm 1:ee089790cdbb 983 * Then need to reconfigure the Codec after power on.
bcostm 1:ee089790cdbb 984 * @retval AUDIO_OK if correct communication, else wrong communication
bcostm 1:ee089790cdbb 985 */
bcostm 1:ee089790cdbb 986 uint8_t BSP_AUDIO_IN_Stop(uint32_t Option)
bcostm 1:ee089790cdbb 987 {
bcostm 1:ee089790cdbb 988 /* Call the Media layer stop function */
bcostm 1:ee089790cdbb 989 HAL_SAI_DMAStop(&haudio_in_sai);
bcostm 1:ee089790cdbb 990
bcostm 1:ee089790cdbb 991 /* Call Audio Codec Stop function */
bcostm 1:ee089790cdbb 992 if(audio_drv->Stop(AUDIO_I2C_ADDRESS, Option) != 0)
bcostm 1:ee089790cdbb 993 {
bcostm 1:ee089790cdbb 994 return AUDIO_ERROR;
bcostm 1:ee089790cdbb 995 }
bcostm 1:ee089790cdbb 996 else
bcostm 1:ee089790cdbb 997 {
bcostm 1:ee089790cdbb 998 if(Option == CODEC_PDWN_HW)
bcostm 1:ee089790cdbb 999 {
bcostm 1:ee089790cdbb 1000 /* Wait at least 100us */
bcostm 1:ee089790cdbb 1001 HAL_Delay(1);
bcostm 1:ee089790cdbb 1002 }
bcostm 1:ee089790cdbb 1003 /* Return AUDIO_OK when all operations are correctly done */
bcostm 1:ee089790cdbb 1004 return AUDIO_OK;
bcostm 1:ee089790cdbb 1005 }
bcostm 1:ee089790cdbb 1006 }
bcostm 1:ee089790cdbb 1007
bcostm 1:ee089790cdbb 1008 /**
bcostm 1:ee089790cdbb 1009 * @brief Pauses the audio file stream.
bcostm 1:ee089790cdbb 1010 * @retval AUDIO_OK if correct communication, else wrong communication
bcostm 1:ee089790cdbb 1011 */
bcostm 1:ee089790cdbb 1012 uint8_t BSP_AUDIO_IN_Pause(void)
bcostm 1:ee089790cdbb 1013 {
bcostm 1:ee089790cdbb 1014 /* Call the Media layer pause function */
bcostm 1:ee089790cdbb 1015 HAL_SAI_DMAPause(&haudio_in_sai);
bcostm 1:ee089790cdbb 1016 /* Return AUDIO_OK when all operations are correctly done */
bcostm 1:ee089790cdbb 1017 return AUDIO_OK;
bcostm 1:ee089790cdbb 1018 }
bcostm 1:ee089790cdbb 1019
bcostm 1:ee089790cdbb 1020 /**
bcostm 1:ee089790cdbb 1021 * @brief Resumes the audio file stream.
bcostm 1:ee089790cdbb 1022 * @retval AUDIO_OK if correct communication, else wrong communication
bcostm 1:ee089790cdbb 1023 */
bcostm 1:ee089790cdbb 1024 uint8_t BSP_AUDIO_IN_Resume(void)
bcostm 1:ee089790cdbb 1025 {
bcostm 1:ee089790cdbb 1026 /* Call the Media layer pause/resume function */
bcostm 1:ee089790cdbb 1027 HAL_SAI_DMAResume(&haudio_in_sai);
bcostm 1:ee089790cdbb 1028 /* Return AUDIO_OK when all operations are correctly done */
bcostm 1:ee089790cdbb 1029 return AUDIO_OK;
bcostm 1:ee089790cdbb 1030 }
bcostm 1:ee089790cdbb 1031
bcostm 1:ee089790cdbb 1032 /**
bcostm 1:ee089790cdbb 1033 * @brief Controls the audio in volume level.
bcostm 1:ee089790cdbb 1034 * @param Volume: Volume level in range 0(Mute)..80(+0dB)..100(+17.625dB)
bcostm 1:ee089790cdbb 1035 * @retval AUDIO_OK if correct communication, else wrong communication
bcostm 1:ee089790cdbb 1036 */
bcostm 1:ee089790cdbb 1037 uint8_t BSP_AUDIO_IN_SetVolume(uint8_t Volume)
bcostm 1:ee089790cdbb 1038 {
bcostm 1:ee089790cdbb 1039 /* Call the codec volume control function with converted volume value */
bcostm 1:ee089790cdbb 1040 if(audio_drv->SetVolume(AUDIO_I2C_ADDRESS, Volume) != 0)
bcostm 1:ee089790cdbb 1041 {
bcostm 1:ee089790cdbb 1042 return AUDIO_ERROR;
bcostm 1:ee089790cdbb 1043 }
bcostm 1:ee089790cdbb 1044 else
bcostm 1:ee089790cdbb 1045 {
bcostm 1:ee089790cdbb 1046 /* Set the Global variable AudioInVolume */
bcostm 1:ee089790cdbb 1047 AudioInVolume = Volume;
bcostm 1:ee089790cdbb 1048 /* Return AUDIO_OK when all operations are correctly done */
bcostm 1:ee089790cdbb 1049 return AUDIO_OK;
bcostm 1:ee089790cdbb 1050 }
bcostm 1:ee089790cdbb 1051 }
bcostm 1:ee089790cdbb 1052
bcostm 1:ee089790cdbb 1053 /**
bcostm 1:ee089790cdbb 1054 * @brief Deinit the audio IN peripherals.
bcostm 1:ee089790cdbb 1055 * @retval None
bcostm 1:ee089790cdbb 1056 */
bcostm 1:ee089790cdbb 1057 void BSP_AUDIO_IN_DeInit(void)
bcostm 1:ee089790cdbb 1058 {
bcostm 1:ee089790cdbb 1059 SAIx_In_DeInit();
bcostm 1:ee089790cdbb 1060 /* DeInit the SAI MSP : this __weak function can be rewritten by the application */
bcostm 1:ee089790cdbb 1061 BSP_AUDIO_IN_MspDeInit(&haudio_in_sai, NULL);
bcostm 1:ee089790cdbb 1062 }
bcostm 1:ee089790cdbb 1063
bcostm 1:ee089790cdbb 1064 /**
bcostm 1:ee089790cdbb 1065 * @brief Rx Transfer completed callbacks.
bcostm 1:ee089790cdbb 1066 * @param hsai: SAI handle
bcostm 1:ee089790cdbb 1067 * @retval None
bcostm 1:ee089790cdbb 1068 */
bcostm 1:ee089790cdbb 1069 void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai)
bcostm 1:ee089790cdbb 1070 {
bcostm 1:ee089790cdbb 1071 /* Call the record update function to get the next buffer to fill and its size (size is ignored) */
bcostm 1:ee089790cdbb 1072 BSP_AUDIO_IN_TransferComplete_CallBack();
bcostm 1:ee089790cdbb 1073 }
bcostm 1:ee089790cdbb 1074
bcostm 1:ee089790cdbb 1075 /**
bcostm 1:ee089790cdbb 1076 * @brief Rx Half Transfer completed callbacks.
bcostm 1:ee089790cdbb 1077 * @param hsai: SAI handle
bcostm 1:ee089790cdbb 1078 * @retval None
bcostm 1:ee089790cdbb 1079 */
bcostm 1:ee089790cdbb 1080 void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai)
bcostm 1:ee089790cdbb 1081 {
bcostm 1:ee089790cdbb 1082 /* Manage the remaining file size and new address offset: This function
bcostm 1:ee089790cdbb 1083 should be coded by user (its prototype is already declared in stm32746g_discovery_audio.h) */
bcostm 1:ee089790cdbb 1084 BSP_AUDIO_IN_HalfTransfer_CallBack();
bcostm 1:ee089790cdbb 1085 }
bcostm 1:ee089790cdbb 1086
bcostm 1:ee089790cdbb 1087 /**
bcostm 1:ee089790cdbb 1088 * @brief User callback when record buffer is filled.
bcostm 1:ee089790cdbb 1089 * @retval None
bcostm 1:ee089790cdbb 1090 */
bcostm 1:ee089790cdbb 1091 __weak void BSP_AUDIO_IN_TransferComplete_CallBack(void)
bcostm 1:ee089790cdbb 1092 {
bcostm 1:ee089790cdbb 1093 /* This function should be implemented by the user application.
bcostm 1:ee089790cdbb 1094 It is called into this driver when the current buffer is filled
bcostm 1:ee089790cdbb 1095 to prepare the next buffer pointer and its size. */
bcostm 1:ee089790cdbb 1096 }
bcostm 1:ee089790cdbb 1097
bcostm 1:ee089790cdbb 1098 /**
bcostm 1:ee089790cdbb 1099 * @brief Manages the DMA Half Transfer complete event.
bcostm 1:ee089790cdbb 1100 * @retval None
bcostm 1:ee089790cdbb 1101 */
bcostm 1:ee089790cdbb 1102 __weak void BSP_AUDIO_IN_HalfTransfer_CallBack(void)
bcostm 1:ee089790cdbb 1103 {
bcostm 1:ee089790cdbb 1104 /* This function should be implemented by the user application.
bcostm 1:ee089790cdbb 1105 It is called into this driver when the current buffer is filled
bcostm 1:ee089790cdbb 1106 to prepare the next buffer pointer and its size. */
bcostm 1:ee089790cdbb 1107 }
bcostm 1:ee089790cdbb 1108
bcostm 1:ee089790cdbb 1109 /**
bcostm 1:ee089790cdbb 1110 * @brief Audio IN Error callback function.
bcostm 1:ee089790cdbb 1111 * @retval None
bcostm 1:ee089790cdbb 1112 */
bcostm 1:ee089790cdbb 1113 __weak void BSP_AUDIO_IN_Error_CallBack(void)
bcostm 1:ee089790cdbb 1114 {
bcostm 1:ee089790cdbb 1115 /* This function is called when an Interrupt due to transfer error on or peripheral
bcostm 1:ee089790cdbb 1116 error occurs. */
bcostm 1:ee089790cdbb 1117 }
bcostm 1:ee089790cdbb 1118
bcostm 1:ee089790cdbb 1119 /**
bcostm 1:ee089790cdbb 1120 * @brief Initializes BSP_AUDIO_IN MSP.
bcostm 1:ee089790cdbb 1121 * @param hsai: SAI handle
bcostm 1:ee089790cdbb 1122 * @param Params
bcostm 1:ee089790cdbb 1123 * @retval None
bcostm 1:ee089790cdbb 1124 */
bcostm 1:ee089790cdbb 1125 __weak void BSP_AUDIO_IN_MspInit(SAI_HandleTypeDef *hsai, void *Params)
bcostm 1:ee089790cdbb 1126 {
bcostm 1:ee089790cdbb 1127 static DMA_HandleTypeDef hdma_sai_rx;
bcostm 1:ee089790cdbb 1128 GPIO_InitTypeDef gpio_init_structure;
bcostm 1:ee089790cdbb 1129
bcostm 1:ee089790cdbb 1130 /* Enable SAI clock */
bcostm 1:ee089790cdbb 1131 AUDIO_IN_SAIx_CLK_ENABLE();
bcostm 1:ee089790cdbb 1132
bcostm 1:ee089790cdbb 1133 /* Enable SD GPIO clock */
bcostm 1:ee089790cdbb 1134 AUDIO_IN_SAIx_SD_ENABLE();
bcostm 1:ee089790cdbb 1135 /* CODEC_SAI pin configuration: SD pin */
bcostm 1:ee089790cdbb 1136 gpio_init_structure.Pin = AUDIO_IN_SAIx_SD_PIN;
bcostm 1:ee089790cdbb 1137 gpio_init_structure.Mode = GPIO_MODE_AF_PP;
bcostm 1:ee089790cdbb 1138 gpio_init_structure.Pull = GPIO_NOPULL;
bcostm 1:ee089790cdbb 1139 gpio_init_structure.Speed = GPIO_SPEED_FAST;
bcostm 1:ee089790cdbb 1140 gpio_init_structure.Alternate = AUDIO_IN_SAIx_SD_AF;
bcostm 1:ee089790cdbb 1141 HAL_GPIO_Init(AUDIO_IN_SAIx_SD_GPIO_PORT, &gpio_init_structure);
bcostm 1:ee089790cdbb 1142
bcostm 1:ee089790cdbb 1143 /* Enable Audio INT GPIO clock */
bcostm 1:ee089790cdbb 1144 AUDIO_IN_INT_GPIO_ENABLE();
bcostm 1:ee089790cdbb 1145 /* Audio INT pin configuration: input */
bcostm 1:ee089790cdbb 1146 gpio_init_structure.Pin = AUDIO_IN_INT_GPIO_PIN;
bcostm 1:ee089790cdbb 1147 gpio_init_structure.Mode = GPIO_MODE_INPUT;
bcostm 1:ee089790cdbb 1148 gpio_init_structure.Pull = GPIO_NOPULL;
bcostm 1:ee089790cdbb 1149 gpio_init_structure.Speed = GPIO_SPEED_FAST;
bcostm 1:ee089790cdbb 1150 HAL_GPIO_Init(AUDIO_IN_INT_GPIO_PORT, &gpio_init_structure);
bcostm 1:ee089790cdbb 1151
bcostm 1:ee089790cdbb 1152 /* Enable the DMA clock */
bcostm 1:ee089790cdbb 1153 AUDIO_IN_SAIx_DMAx_CLK_ENABLE();
bcostm 1:ee089790cdbb 1154
bcostm 1:ee089790cdbb 1155 if(hsai->Instance == AUDIO_IN_SAIx)
bcostm 1:ee089790cdbb 1156 {
bcostm 1:ee089790cdbb 1157 /* Configure the hdma_sai_rx handle parameters */
bcostm 1:ee089790cdbb 1158 hdma_sai_rx.Init.Channel = AUDIO_IN_SAIx_DMAx_CHANNEL;
bcostm 1:ee089790cdbb 1159 hdma_sai_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
bcostm 1:ee089790cdbb 1160 hdma_sai_rx.Init.PeriphInc = DMA_PINC_DISABLE;
bcostm 1:ee089790cdbb 1161 hdma_sai_rx.Init.MemInc = DMA_MINC_ENABLE;
bcostm 1:ee089790cdbb 1162 hdma_sai_rx.Init.PeriphDataAlignment = AUDIO_IN_SAIx_DMAx_PERIPH_DATA_SIZE;
bcostm 1:ee089790cdbb 1163 hdma_sai_rx.Init.MemDataAlignment = AUDIO_IN_SAIx_DMAx_MEM_DATA_SIZE;
bcostm 1:ee089790cdbb 1164 hdma_sai_rx.Init.Mode = DMA_CIRCULAR;
bcostm 1:ee089790cdbb 1165 hdma_sai_rx.Init.Priority = DMA_PRIORITY_HIGH;
bcostm 1:ee089790cdbb 1166 hdma_sai_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
bcostm 1:ee089790cdbb 1167 hdma_sai_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
bcostm 1:ee089790cdbb 1168 hdma_sai_rx.Init.MemBurst = DMA_MBURST_SINGLE;
bcostm 1:ee089790cdbb 1169 hdma_sai_rx.Init.PeriphBurst = DMA_MBURST_SINGLE;
bcostm 1:ee089790cdbb 1170
bcostm 1:ee089790cdbb 1171 hdma_sai_rx.Instance = AUDIO_IN_SAIx_DMAx_STREAM;
bcostm 1:ee089790cdbb 1172
bcostm 1:ee089790cdbb 1173 /* Associate the DMA handle */
bcostm 1:ee089790cdbb 1174 __HAL_LINKDMA(hsai, hdmarx, hdma_sai_rx);
bcostm 1:ee089790cdbb 1175
bcostm 1:ee089790cdbb 1176 /* Deinitialize the Stream for new transfer */
bcostm 1:ee089790cdbb 1177 HAL_DMA_DeInit(&hdma_sai_rx);
bcostm 1:ee089790cdbb 1178
bcostm 1:ee089790cdbb 1179 /* Configure the DMA Stream */
bcostm 1:ee089790cdbb 1180 HAL_DMA_Init(&hdma_sai_rx);
bcostm 1:ee089790cdbb 1181 }
bcostm 1:ee089790cdbb 1182
bcostm 1:ee089790cdbb 1183 /* SAI DMA IRQ Channel configuration */
adustm 2:458ab1edf6b2 1184 #if ( __MBED__ == 1)
adustm 2:458ab1edf6b2 1185 IRQn_Type irqn = (IRQn_Type)(AUDIO_IN_SAIx_DMAx_IRQ);
adustm 2:458ab1edf6b2 1186 NVIC_ClearPendingIRQ(irqn);
adustm 2:458ab1edf6b2 1187 NVIC_DisableIRQ(irqn);
adustm 2:458ab1edf6b2 1188 NVIC_SetPriority(irqn, AUDIO_IN_IRQ_PREPRIO);
adustm 2:458ab1edf6b2 1189 NVIC_SetVector(irqn, (uint32_t)AUDIO_IN_SAIx_DMAx_IRQHandler);
adustm 2:458ab1edf6b2 1190 NVIC_EnableIRQ(irqn);
adustm 2:458ab1edf6b2 1191 #else
bcostm 1:ee089790cdbb 1192 HAL_NVIC_SetPriority(AUDIO_IN_SAIx_DMAx_IRQ, AUDIO_IN_IRQ_PREPRIO, 0);
bcostm 1:ee089790cdbb 1193 HAL_NVIC_EnableIRQ(AUDIO_IN_SAIx_DMAx_IRQ);
adustm 2:458ab1edf6b2 1194 #endif
bcostm 1:ee089790cdbb 1195
bcostm 1:ee089790cdbb 1196 /* Audio INT IRQ Channel configuration */
adustm 2:458ab1edf6b2 1197 #if ( __MBED__ == 1)
adustm 2:458ab1edf6b2 1198 irqn = (IRQn_Type)(AUDIO_IN_INT_IRQ);
adustm 2:458ab1edf6b2 1199 NVIC_ClearPendingIRQ(irqn);
adustm 2:458ab1edf6b2 1200 NVIC_DisableIRQ(irqn);
adustm 2:458ab1edf6b2 1201 NVIC_SetPriority(irqn, AUDIO_IN_IRQ_PREPRIO);
adustm 2:458ab1edf6b2 1202 NVIC_SetVector(irqn, (uint32_t)AUDIO_IN_INT_IRQHandler);
adustm 2:458ab1edf6b2 1203 NVIC_EnableIRQ(irqn);
adustm 2:458ab1edf6b2 1204 #else
bcostm 1:ee089790cdbb 1205 HAL_NVIC_SetPriority(AUDIO_IN_INT_IRQ, AUDIO_IN_IRQ_PREPRIO, 0);
bcostm 1:ee089790cdbb 1206 HAL_NVIC_EnableIRQ(AUDIO_IN_INT_IRQ);
adustm 2:458ab1edf6b2 1207 #endif
bcostm 1:ee089790cdbb 1208 }
bcostm 1:ee089790cdbb 1209
bcostm 1:ee089790cdbb 1210 /**
bcostm 1:ee089790cdbb 1211 * @brief DeInitializes BSP_AUDIO_IN MSP.
bcostm 1:ee089790cdbb 1212 * @param hsai: SAI handle
bcostm 1:ee089790cdbb 1213 * @param Params
bcostm 1:ee089790cdbb 1214 * @retval None
bcostm 1:ee089790cdbb 1215 */
bcostm 1:ee089790cdbb 1216 __weak void BSP_AUDIO_IN_MspDeInit(SAI_HandleTypeDef *hsai, void *Params)
bcostm 1:ee089790cdbb 1217 {
bcostm 1:ee089790cdbb 1218 GPIO_InitTypeDef gpio_init_structure;
bcostm 1:ee089790cdbb 1219
bcostm 1:ee089790cdbb 1220 static DMA_HandleTypeDef hdma_sai_rx;
bcostm 1:ee089790cdbb 1221
bcostm 1:ee089790cdbb 1222 /* SAI IN DMA IRQ Channel deactivation */
bcostm 1:ee089790cdbb 1223 HAL_NVIC_DisableIRQ(AUDIO_IN_SAIx_DMAx_IRQ);
bcostm 1:ee089790cdbb 1224
bcostm 1:ee089790cdbb 1225 if(hsai->Instance == AUDIO_IN_SAIx)
bcostm 1:ee089790cdbb 1226 {
bcostm 1:ee089790cdbb 1227 /* Deinitialize the Stream for new transfer */
bcostm 1:ee089790cdbb 1228 HAL_DMA_DeInit(&hdma_sai_rx);
bcostm 1:ee089790cdbb 1229 }
bcostm 1:ee089790cdbb 1230
bcostm 1:ee089790cdbb 1231 /* Disable SAI block */
bcostm 1:ee089790cdbb 1232 __HAL_SAI_DISABLE(hsai);
bcostm 1:ee089790cdbb 1233
bcostm 1:ee089790cdbb 1234 /* Disable pin: SD pin */
bcostm 1:ee089790cdbb 1235 gpio_init_structure.Pin = AUDIO_IN_SAIx_SD_PIN;
bcostm 1:ee089790cdbb 1236 HAL_GPIO_DeInit(AUDIO_IN_SAIx_SD_GPIO_PORT, gpio_init_structure.Pin);
bcostm 1:ee089790cdbb 1237
bcostm 1:ee089790cdbb 1238 /* Disable SAI clock */
bcostm 1:ee089790cdbb 1239 AUDIO_IN_SAIx_CLK_DISABLE();
bcostm 1:ee089790cdbb 1240
bcostm 1:ee089790cdbb 1241 /* GPIO pins clock and DMA clock can be shut down in the application
bcostm 1:ee089790cdbb 1242 by surcharging this __weak function */
bcostm 1:ee089790cdbb 1243 }
bcostm 1:ee089790cdbb 1244
bcostm 1:ee089790cdbb 1245
bcostm 1:ee089790cdbb 1246 /*******************************************************************************
bcostm 1:ee089790cdbb 1247 Static Functions
bcostm 1:ee089790cdbb 1248 *******************************************************************************/
bcostm 1:ee089790cdbb 1249
bcostm 1:ee089790cdbb 1250 /**
bcostm 1:ee089790cdbb 1251 * @brief Initializes the input Audio Codec audio interface (SAI).
bcostm 1:ee089790cdbb 1252 * @param SaiOutMode: SAI_MODEMASTER_TX (for record and playback in parallel)
bcostm 1:ee089790cdbb 1253 * or SAI_MODEMASTER_RX (for record only).
bcostm 1:ee089790cdbb 1254 * @param SlotActive: CODEC_AUDIOFRAME_SLOT_02 or CODEC_AUDIOFRAME_SLOT_13
bcostm 1:ee089790cdbb 1255 * @param AudioFreq: Audio frequency to be configured for the SAI peripheral.
bcostm 1:ee089790cdbb 1256 * @retval None
bcostm 1:ee089790cdbb 1257 */
bcostm 1:ee089790cdbb 1258 static void SAIx_In_Init(uint32_t SaiOutMode, uint32_t SlotActive, uint32_t AudioFreq)
bcostm 1:ee089790cdbb 1259 {
bcostm 1:ee089790cdbb 1260 /* Initialize SAI2 block A in MASTER RX */
bcostm 1:ee089790cdbb 1261 /* Initialize the haudio_out_sai Instance parameter */
bcostm 1:ee089790cdbb 1262 haudio_out_sai.Instance = AUDIO_OUT_SAIx;
bcostm 1:ee089790cdbb 1263
bcostm 1:ee089790cdbb 1264 /* Disable SAI peripheral to allow access to SAI internal registers */
bcostm 1:ee089790cdbb 1265 __HAL_SAI_DISABLE(&haudio_out_sai);
bcostm 1:ee089790cdbb 1266
bcostm 1:ee089790cdbb 1267 /* Configure SAI_Block_x
bcostm 1:ee089790cdbb 1268 LSBFirst: Disabled
bcostm 1:ee089790cdbb 1269 DataSize: 16 */
bcostm 1:ee089790cdbb 1270 haudio_out_sai.Init.AudioFrequency = AudioFreq;
bcostm 1:ee089790cdbb 1271 haudio_out_sai.Init.AudioMode = SaiOutMode;
bcostm 1:ee089790cdbb 1272 haudio_out_sai.Init.NoDivider = SAI_MASTERDIVIDER_ENABLED;
bcostm 1:ee089790cdbb 1273 haudio_out_sai.Init.Protocol = SAI_FREE_PROTOCOL;
bcostm 1:ee089790cdbb 1274 haudio_out_sai.Init.DataSize = SAI_DATASIZE_16;
bcostm 1:ee089790cdbb 1275 haudio_out_sai.Init.FirstBit = SAI_FIRSTBIT_MSB;
bcostm 1:ee089790cdbb 1276 haudio_out_sai.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
bcostm 1:ee089790cdbb 1277 haudio_out_sai.Init.Synchro = SAI_ASYNCHRONOUS;
bcostm 1:ee089790cdbb 1278 haudio_out_sai.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLED;
bcostm 1:ee089790cdbb 1279 haudio_out_sai.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
bcostm 1:ee089790cdbb 1280
bcostm 1:ee089790cdbb 1281 /* Configure SAI_Block_x Frame
bcostm 1:ee089790cdbb 1282 Frame Length: 64
bcostm 1:ee089790cdbb 1283 Frame active Length: 32
bcostm 1:ee089790cdbb 1284 FS Definition: Start frame + Channel Side identification
bcostm 1:ee089790cdbb 1285 FS Polarity: FS active Low
bcostm 1:ee089790cdbb 1286 FS Offset: FS asserted one bit before the first bit of slot 0 */
bcostm 1:ee089790cdbb 1287 haudio_out_sai.FrameInit.FrameLength = 64;
bcostm 1:ee089790cdbb 1288 haudio_out_sai.FrameInit.ActiveFrameLength = 32;
bcostm 1:ee089790cdbb 1289 haudio_out_sai.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
bcostm 1:ee089790cdbb 1290 haudio_out_sai.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
bcostm 1:ee089790cdbb 1291 haudio_out_sai.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
bcostm 1:ee089790cdbb 1292
bcostm 1:ee089790cdbb 1293 /* Configure SAI Block_x Slot
bcostm 1:ee089790cdbb 1294 Slot First Bit Offset: 0
bcostm 1:ee089790cdbb 1295 Slot Size : 16
bcostm 1:ee089790cdbb 1296 Slot Number: 4
bcostm 1:ee089790cdbb 1297 Slot Active: All slot actives */
bcostm 1:ee089790cdbb 1298 haudio_out_sai.SlotInit.FirstBitOffset = 0;
bcostm 1:ee089790cdbb 1299 haudio_out_sai.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
bcostm 1:ee089790cdbb 1300 haudio_out_sai.SlotInit.SlotNumber = 4;
bcostm 1:ee089790cdbb 1301 haudio_out_sai.SlotInit.SlotActive = SlotActive;
bcostm 1:ee089790cdbb 1302
bcostm 1:ee089790cdbb 1303 HAL_SAI_Init(&haudio_out_sai);
bcostm 1:ee089790cdbb 1304
bcostm 1:ee089790cdbb 1305 /* Initialize SAI2 block B in SLAVE RX synchronous from SAI2 block A */
bcostm 1:ee089790cdbb 1306 /* Initialize the haudio_in_sai Instance parameter */
bcostm 1:ee089790cdbb 1307 haudio_in_sai.Instance = AUDIO_IN_SAIx;
bcostm 1:ee089790cdbb 1308
bcostm 1:ee089790cdbb 1309 /* Disable SAI peripheral to allow access to SAI internal registers */
bcostm 1:ee089790cdbb 1310 __HAL_SAI_DISABLE(&haudio_in_sai);
bcostm 1:ee089790cdbb 1311
bcostm 1:ee089790cdbb 1312 /* Configure SAI_Block_x
bcostm 1:ee089790cdbb 1313 LSBFirst: Disabled
bcostm 1:ee089790cdbb 1314 DataSize: 16 */
bcostm 1:ee089790cdbb 1315 haudio_in_sai.Init.AudioFrequency = AudioFreq;
bcostm 1:ee089790cdbb 1316 haudio_in_sai.Init.AudioMode = SAI_MODESLAVE_RX;
bcostm 1:ee089790cdbb 1317 haudio_in_sai.Init.NoDivider = SAI_MASTERDIVIDER_ENABLED;
bcostm 1:ee089790cdbb 1318 haudio_in_sai.Init.Protocol = SAI_FREE_PROTOCOL;
bcostm 1:ee089790cdbb 1319 haudio_in_sai.Init.DataSize = SAI_DATASIZE_16;
bcostm 1:ee089790cdbb 1320 haudio_in_sai.Init.FirstBit = SAI_FIRSTBIT_MSB;
bcostm 1:ee089790cdbb 1321 haudio_in_sai.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
bcostm 1:ee089790cdbb 1322 haudio_in_sai.Init.Synchro = SAI_SYNCHRONOUS;
bcostm 1:ee089790cdbb 1323 haudio_in_sai.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLED;
bcostm 1:ee089790cdbb 1324 haudio_in_sai.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
bcostm 1:ee089790cdbb 1325
bcostm 1:ee089790cdbb 1326 /* Configure SAI_Block_x Frame
bcostm 1:ee089790cdbb 1327 Frame Length: 64
bcostm 1:ee089790cdbb 1328 Frame active Length: 32
bcostm 1:ee089790cdbb 1329 FS Definition: Start frame + Channel Side identification
bcostm 1:ee089790cdbb 1330 FS Polarity: FS active Low
bcostm 1:ee089790cdbb 1331 FS Offset: FS asserted one bit before the first bit of slot 0 */
bcostm 1:ee089790cdbb 1332 haudio_in_sai.FrameInit.FrameLength = 64;
bcostm 1:ee089790cdbb 1333 haudio_in_sai.FrameInit.ActiveFrameLength = 32;
bcostm 1:ee089790cdbb 1334 haudio_in_sai.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
bcostm 1:ee089790cdbb 1335 haudio_in_sai.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
bcostm 1:ee089790cdbb 1336 haudio_in_sai.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
bcostm 1:ee089790cdbb 1337
bcostm 1:ee089790cdbb 1338 /* Configure SAI Block_x Slot
bcostm 1:ee089790cdbb 1339 Slot First Bit Offset: 0
bcostm 1:ee089790cdbb 1340 Slot Size : 16
bcostm 1:ee089790cdbb 1341 Slot Number: 4
bcostm 1:ee089790cdbb 1342 Slot Active: All slot active */
bcostm 1:ee089790cdbb 1343 haudio_in_sai.SlotInit.FirstBitOffset = 0;
bcostm 1:ee089790cdbb 1344 haudio_in_sai.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
bcostm 1:ee089790cdbb 1345 haudio_in_sai.SlotInit.SlotNumber = 4;
bcostm 1:ee089790cdbb 1346 haudio_in_sai.SlotInit.SlotActive = SlotActive;
bcostm 1:ee089790cdbb 1347
bcostm 1:ee089790cdbb 1348 HAL_SAI_Init(&haudio_in_sai);
bcostm 1:ee089790cdbb 1349
bcostm 1:ee089790cdbb 1350 /* Enable SAI peripheral to generate MCLK */
bcostm 1:ee089790cdbb 1351 __HAL_SAI_ENABLE(&haudio_out_sai);
bcostm 1:ee089790cdbb 1352
bcostm 1:ee089790cdbb 1353 /* Enable SAI peripheral */
bcostm 1:ee089790cdbb 1354 __HAL_SAI_ENABLE(&haudio_in_sai);
bcostm 1:ee089790cdbb 1355 }
bcostm 1:ee089790cdbb 1356
bcostm 1:ee089790cdbb 1357
bcostm 1:ee089790cdbb 1358
bcostm 1:ee089790cdbb 1359 /**
bcostm 1:ee089790cdbb 1360 * @brief Deinitializes the output Audio Codec audio interface (SAI).
bcostm 1:ee089790cdbb 1361 * @retval None
bcostm 1:ee089790cdbb 1362 */
bcostm 1:ee089790cdbb 1363 static void SAIx_In_DeInit(void)
bcostm 1:ee089790cdbb 1364 {
bcostm 1:ee089790cdbb 1365 /* Initialize the haudio_in_sai Instance parameter */
bcostm 1:ee089790cdbb 1366 haudio_in_sai.Instance = AUDIO_IN_SAIx;
bcostm 1:ee089790cdbb 1367
bcostm 1:ee089790cdbb 1368 /* Disable SAI peripheral */
bcostm 1:ee089790cdbb 1369 __HAL_SAI_DISABLE(&haudio_in_sai);
bcostm 1:ee089790cdbb 1370
bcostm 1:ee089790cdbb 1371 HAL_SAI_DeInit(&haudio_in_sai);
bcostm 1:ee089790cdbb 1372 }
bcostm 1:ee089790cdbb 1373
adustm 2:458ab1edf6b2 1374 /**
adustm 2:458ab1edf6b2 1375 * @brief This function handles External line 15_10 interrupt request.
adustm 2:458ab1edf6b2 1376 * @param None
adustm 2:458ab1edf6b2 1377 * @retval None
adustm 2:458ab1edf6b2 1378 */
adustm 2:458ab1edf6b2 1379 static void AUDIO_IN_INT_IRQHandler(void)
adustm 2:458ab1edf6b2 1380 {
adustm 2:458ab1edf6b2 1381 /* Interrupt handler shared between SD_DETECT pin, USER_KEY button and touch screen interrupt */
adustm 2:458ab1edf6b2 1382 if (__HAL_GPIO_EXTI_GET_IT(AUDIO_IN_INT_GPIO_PIN) != RESET)
adustm 2:458ab1edf6b2 1383 {
adustm 2:458ab1edf6b2 1384 HAL_GPIO_EXTI_IRQHandler(AUDIO_IN_INT_GPIO_PIN); /* Audio Interrupt */
adustm 2:458ab1edf6b2 1385 }
adustm 2:458ab1edf6b2 1386 }
adustm 2:458ab1edf6b2 1387
adustm 2:458ab1edf6b2 1388 /**
adustm 2:458ab1edf6b2 1389 * @brief This function handles DMA2 Stream 7 interrupt request.
adustm 2:458ab1edf6b2 1390 * @param None
adustm 2:458ab1edf6b2 1391 * @retval None
adustm 2:458ab1edf6b2 1392 */
adustm 2:458ab1edf6b2 1393 static void AUDIO_IN_SAIx_DMAx_IRQHandler(void)
adustm 2:458ab1edf6b2 1394 {
adustm 2:458ab1edf6b2 1395 HAL_DMA_IRQHandler(haudio_in_sai.hdmarx);
adustm 2:458ab1edf6b2 1396 }
adustm 2:458ab1edf6b2 1397
adustm 2:458ab1edf6b2 1398 /**
adustm 2:458ab1edf6b2 1399 * @brief This function handles DMA2 Stream 6 interrupt request.
adustm 2:458ab1edf6b2 1400 * @param None
adustm 2:458ab1edf6b2 1401 * @retval None
adustm 2:458ab1edf6b2 1402 */
adustm 2:458ab1edf6b2 1403 static void AUDIO_OUT_SAIx_DMAx_IRQHandler(void)
adustm 2:458ab1edf6b2 1404 {
adustm 2:458ab1edf6b2 1405 HAL_DMA_IRQHandler(haudio_out_sai.hdmatx);
adustm 2:458ab1edf6b2 1406 }
bcostm 1:ee089790cdbb 1407
bcostm 1:ee089790cdbb 1408 /**
bcostm 1:ee089790cdbb 1409 * @}
bcostm 1:ee089790cdbb 1410 */
bcostm 1:ee089790cdbb 1411
bcostm 1:ee089790cdbb 1412 /**
bcostm 1:ee089790cdbb 1413 * @}
bcostm 1:ee089790cdbb 1414 */
bcostm 1:ee089790cdbb 1415
bcostm 1:ee089790cdbb 1416 /**
bcostm 1:ee089790cdbb 1417 * @}
bcostm 1:ee089790cdbb 1418 */
bcostm 1:ee089790cdbb 1419
bcostm 1:ee089790cdbb 1420 /**
bcostm 1:ee089790cdbb 1421 * @}
bcostm 1:ee089790cdbb 1422 */
bcostm 1:ee089790cdbb 1423
bcostm 1:ee089790cdbb 1424 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/