BSP files for STM32H747I-Discovery Copy from ST Cube delivery

Dependents:   DISCO_H747I_LCD_demo DISCO_H747I_AUDIO_demo

Committer:
Jerome Coutant
Date:
Wed Sep 25 17:50:02 2019 +0200
Revision:
1:9716849a8de8
Parent:
0:146cf26a9bbb
Child:
2:53134782cc12
Update to remove PDM

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jerome Coutant 0:146cf26a9bbb 1 /**
Jerome Coutant 0:146cf26a9bbb 2 ******************************************************************************
Jerome Coutant 0:146cf26a9bbb 3 * @file stm32h747i_discovery_audio.c
Jerome Coutant 0:146cf26a9bbb 4 * @author MCD Application Team
Jerome Coutant 0:146cf26a9bbb 5 * @brief This file provides the Audio driver for the STM32H747I-DISCOVERY
Jerome Coutant 0:146cf26a9bbb 6 * board.
Jerome Coutant 0:146cf26a9bbb 7 @verbatim
Jerome Coutant 0:146cf26a9bbb 8 How To use this driver:
Jerome Coutant 0:146cf26a9bbb 9 -----------------------
Jerome Coutant 0:146cf26a9bbb 10 + This driver supports STM32H7xx devices on STM32H747I-DISCOVERY (MB1248) Discovery boards.
Jerome Coutant 0:146cf26a9bbb 11 + Call the function BSP_AUDIO_OUT_Init(
Jerome Coutant 0:146cf26a9bbb 12 OutputDevice: physical output mode (OUTPUT_DEVICE_SPEAKER,
Jerome Coutant 0:146cf26a9bbb 13 OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH)
Jerome Coutant 0:146cf26a9bbb 14 Volume : Initial volume to be set (0 is min (mute), 100 is max (100%)
Jerome Coutant 0:146cf26a9bbb 15 AudioFreq : Audio frequency in Hz (8000, 16000, 22500, 32000...)
Jerome Coutant 0:146cf26a9bbb 16 this parameter is relative to the audio file/stream type.
Jerome Coutant 0:146cf26a9bbb 17 )
Jerome Coutant 0:146cf26a9bbb 18 This function configures all the hardware required for the audio application (codec, I2C, SAI,
Jerome Coutant 0:146cf26a9bbb 19 GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if configuration is OK.
Jerome Coutant 0:146cf26a9bbb 20 If the returned value is different from AUDIO_OK or the function is stuck then the communication with
Jerome Coutant 0:146cf26a9bbb 21 the codec has failed (try to un-plug the power or reset device in this case).
Jerome Coutant 0:146cf26a9bbb 22 - OUTPUT_DEVICE_SPEAKER : only speaker will be set as output for the audio stream.
Jerome Coutant 0:146cf26a9bbb 23 - OUTPUT_DEVICE_HEADPHONE: only headphones will be set as output for the audio stream.
Jerome Coutant 0:146cf26a9bbb 24 - OUTPUT_DEVICE_BOTH : both Speaker and Headphone are used as outputs for the audio stream
Jerome Coutant 0:146cf26a9bbb 25 at the same time.
Jerome Coutant 0:146cf26a9bbb 26 Note. On STM32H747I-DISCOVERY SAI_DMA is configured in CIRCULAR mode. Due to this the application
Jerome Coutant 0:146cf26a9bbb 27 does NOT need to call BSP_AUDIO_OUT_ChangeBuffer() to assure streaming.
Jerome Coutant 0:146cf26a9bbb 28 + Call the function BSP_AUDIO_OUT_Play(
Jerome Coutant 0:146cf26a9bbb 29 pBuffer: pointer to the audio data file address
Jerome Coutant 0:146cf26a9bbb 30 Size : size of the buffer to be sent in Bytes
Jerome Coutant 0:146cf26a9bbb 31 )
Jerome Coutant 0:146cf26a9bbb 32 to start playing (for the first time) from the audio file/stream.
Jerome Coutant 0:146cf26a9bbb 33 + Call the function BSP_AUDIO_OUT_Pause() to pause playing
Jerome Coutant 0:146cf26a9bbb 34 + Call the function BSP_AUDIO_OUT_Resume() to resume playing.
Jerome Coutant 0:146cf26a9bbb 35 Note. After calling BSP_AUDIO_OUT_Pause() function for pause, only BSP_AUDIO_OUT_Resume() should be called
Jerome Coutant 0:146cf26a9bbb 36 for resume (it is not allowed to call BSP_AUDIO_OUT_Play() in this case).
Jerome Coutant 0:146cf26a9bbb 37 Note. This function should be called only when the audio file is played or paused (not stopped).
Jerome Coutant 0:146cf26a9bbb 38 + For each mode, you may need to implement the relative callback functions into your code.
Jerome Coutant 0:146cf26a9bbb 39 The Callback functions are named BSP_AUDIO_OUT_XXX_CallBack() and only their prototypes are declared in
Jerome Coutant 0:146cf26a9bbb 40 the stm32h747i_discovery_audio.h file. (refer to the example for more details on the callbacks implementations)
Jerome Coutant 0:146cf26a9bbb 41 + To Stop playing, to modify the volume level, the frequency, the audio frame slot,
Jerome Coutant 0:146cf26a9bbb 42 the device output mode the mute or the stop, use the functions: BSP_AUDIO_OUT_SetVolume(),
Jerome Coutant 0:146cf26a9bbb 43 AUDIO_OUT_SetFrequency(), BSP_AUDIO_OUT_SetAudioFrameSlot(), BSP_AUDIO_OUT_SetOutputMode(),
Jerome Coutant 0:146cf26a9bbb 44 BSP_AUDIO_OUT_SetMute() and BSP_AUDIO_OUT_Stop().
Jerome Coutant 0:146cf26a9bbb 45
Jerome Coutant 0:146cf26a9bbb 46 + Call the function BSP_AUDIO_IN_Init(
Jerome Coutant 0:146cf26a9bbb 47 AudioFreq: Audio frequency in Hz (8000, 16000, 22500, 32000...)
Jerome Coutant 0:146cf26a9bbb 48 this parameter is relative to the audio file/stream type.
Jerome Coutant 0:146cf26a9bbb 49 BitRes: Bit resolution fixed to 16bit
Jerome Coutant 0:146cf26a9bbb 50 ChnlNbr: Number of channel to be configured for the DFSDM peripheral
Jerome Coutant 0:146cf26a9bbb 51 )
Jerome Coutant 0:146cf26a9bbb 52 This function configures all the hardware required for the audio in application (channels,
Jerome Coutant 0:146cf26a9bbb 53 Clock source for SAI PDM periphiral, GPIOs, DMA and interrupt if needed).
Jerome Coutant 0:146cf26a9bbb 54 This function returns AUDIO_OK if configuration is OK.If the returned value is different from AUDIO_OK then
Jerome Coutant 0:146cf26a9bbb 55 the configuration should be wrong.
Jerome Coutant 0:146cf26a9bbb 56 + Call the function BSP_AUDIO_IN_AllocScratch(
Jerome Coutant 0:146cf26a9bbb 57 pScratch: pointer to scratch tables
Jerome Coutant 0:146cf26a9bbb 58 size: size of scratch buffer)
Jerome Coutant 0:146cf26a9bbb 59 This function must be called before BSP_AUDIO_IN_RECORD() to allocate buffer scratch for each DFSDM channel
Jerome Coutant 0:146cf26a9bbb 60 and its size.
Jerome Coutant 0:146cf26a9bbb 61 Note: These buffers scratch are used as intermidiate buffers to collect data within final record buffer.
Jerome Coutant 0:146cf26a9bbb 62 size is the total size of the four buffers scratch; If size is 512 then the size of each is 128.
Jerome Coutant 0:146cf26a9bbb 63 This function must be called after BSP_AUDIO_IN_Init()
Jerome Coutant 0:146cf26a9bbb 64 + Call the function BSP_AUDIO_IN_RECORD(
Jerome Coutant 0:146cf26a9bbb 65 pBuf: pointer to the recorded audio data file address
Jerome Coutant 0:146cf26a9bbb 66 Size: size of the buffer to be written in Bytes
Jerome Coutant 0:146cf26a9bbb 67 )
Jerome Coutant 0:146cf26a9bbb 68 to start recording from microphones.
Jerome Coutant 0:146cf26a9bbb 69
Jerome Coutant 0:146cf26a9bbb 70 + Call the function BSP_AUDIO_IN_Pause() to pause recording
Jerome Coutant 0:146cf26a9bbb 71 + Call the function BSP_AUDIO_IN_Resume() to recording playing.
Jerome Coutant 0:146cf26a9bbb 72 Note. After calling BSP_AUDIO_IN_Pause() function for pause, only BSP_AUDIO_IN_Resume() should be called
Jerome Coutant 0:146cf26a9bbb 73 for resume (it is not allowed to call BSP_AUDIO_IN_RECORD() in this case).
Jerome Coutant 0:146cf26a9bbb 74 + Call the function BSP_AUDIO_IN_Stop() to stop recording
Jerome Coutant 0:146cf26a9bbb 75 + For each mode, you may need to implement the relative callback functions into your code.
Jerome Coutant 0:146cf26a9bbb 76 The Callback functions are named BSP_AUDIO_IN_XXX_CallBack() and only their prototypes are declared in
Jerome Coutant 0:146cf26a9bbb 77 the stm32h747i_discovery_audio.h file. (refer to the example for more details on the callbacks implementations)
Jerome Coutant 0:146cf26a9bbb 78 + Call the function BSP_AUDIO_IN_SelectInterface(uint32_t Interface) to select one of the two interfaces
Jerome Coutant 0:146cf26a9bbb 79 available on the STM32H747I-Discovery board: SAI or PDM. This function is to be called before BSP_AUDIO_IN_InitEx().
Jerome Coutant 0:146cf26a9bbb 80 + Call the function BSP_AUDIO_IN_GetInterface() to get the current used interface.
Jerome Coutant 0:146cf26a9bbb 81 + Call the function BSP_AUDIO_IN_PDMToPCM_Init(uint32_t AudioFreq, uint32_t ChnlNbrIn, uint32_t ChnlNbrOut)
Jerome Coutant 0:146cf26a9bbb 82 to init PDM filters if the libPDMFilter is used for audio data filtering.
Jerome Coutant 0:146cf26a9bbb 83 + Call the function BSP_AUDIO_IN_PDMToPCM(uint16_t* PDMBuf, uint16_t* PCMBuf) to filter PDM data to PCM format
Jerome Coutant 0:146cf26a9bbb 84 if the libPDMFilter library is used for audio data filtering.
Jerome Coutant 0:146cf26a9bbb 85
Jerome Coutant 0:146cf26a9bbb 86 Driver architecture:
Jerome Coutant 0:146cf26a9bbb 87 --------------------
Jerome Coutant 0:146cf26a9bbb 88 + This driver provides the High Audio Layer: consists of the function API exported in the stm32h747i_discovery_audio.h file
Jerome Coutant 0:146cf26a9bbb 89 (BSP_AUDIO_OUT_Init(), BSP_AUDIO_OUT_Play() ...)
Jerome Coutant 0:146cf26a9bbb 90 + This driver provide also the Media Access Layer (MAL): which consists of functions allowing to access the media containing/
Jerome Coutant 0:146cf26a9bbb 91 providing the audio file/stream. These functions are also included as local functions into
Jerome Coutant 0:146cf26a9bbb 92 the stm32h747i_discovery_audio.c file (DFSDMx_Init(), DFSDMx_DeInit(), SAIx_Init() and SAIx_DeInit())
Jerome Coutant 0:146cf26a9bbb 93
Jerome Coutant 0:146cf26a9bbb 94 Known Limitations:
Jerome Coutant 0:146cf26a9bbb 95 ------------------
Jerome Coutant 0:146cf26a9bbb 96 1- If the TDM Format used to play in parallel 2 audio Stream (the first Stream is configured in codec SLOT0 and second
Jerome Coutant 0:146cf26a9bbb 97 Stream in SLOT1) the Pause/Resume, volume and mute feature will control the both streams.
Jerome Coutant 0:146cf26a9bbb 98 2- Parsing of audio file is not implemented (in order to determine audio file properties: Mono/Stereo, Data size,
Jerome Coutant 0:146cf26a9bbb 99 File size, Audio Frequency, Audio Data header size ...). The configuration is fixed for the given audio file.
Jerome Coutant 0:146cf26a9bbb 100 3- Supports only Stereo audio streaming.
Jerome Coutant 0:146cf26a9bbb 101 4- Supports only 16-bits audio data size.
Jerome Coutant 0:146cf26a9bbb 102 @endverbatim
Jerome Coutant 0:146cf26a9bbb 103 ******************************************************************************
Jerome Coutant 0:146cf26a9bbb 104 * @attention
Jerome Coutant 0:146cf26a9bbb 105 *
Jerome Coutant 0:146cf26a9bbb 106 * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
Jerome Coutant 0:146cf26a9bbb 107 * All rights reserved.</center></h2>
Jerome Coutant 0:146cf26a9bbb 108 *
Jerome Coutant 0:146cf26a9bbb 109 * This software component is licensed by ST under BSD 3-Clause license,
Jerome Coutant 0:146cf26a9bbb 110 * the "License"; You may not use this file except in compliance with the
Jerome Coutant 0:146cf26a9bbb 111 * License. You may obtain a copy of the License at:
Jerome Coutant 0:146cf26a9bbb 112 * opensource.org/licenses/BSD-3-Clause
Jerome Coutant 0:146cf26a9bbb 113 *
Jerome Coutant 0:146cf26a9bbb 114 ******************************************************************************
Jerome Coutant 0:146cf26a9bbb 115 */
Jerome Coutant 0:146cf26a9bbb 116 /* Includes ------------------------------------------------------------------*/
Jerome Coutant 0:146cf26a9bbb 117 #include "stm32h747i_discovery_audio.h"
Jerome Coutant 1:9716849a8de8 118 #include "mbed_assert.h"
Jerome Coutant 0:146cf26a9bbb 119
Jerome Coutant 0:146cf26a9bbb 120 /** @addtogroup BSP
Jerome Coutant 0:146cf26a9bbb 121 * @{
Jerome Coutant 0:146cf26a9bbb 122 */
Jerome Coutant 0:146cf26a9bbb 123
Jerome Coutant 0:146cf26a9bbb 124 /** @addtogroup STM32H747I_DISCOVERY
Jerome Coutant 0:146cf26a9bbb 125 * @{
Jerome Coutant 0:146cf26a9bbb 126 */
Jerome Coutant 0:146cf26a9bbb 127
Jerome Coutant 0:146cf26a9bbb 128 /** @defgroup STM32H747I_DISCOVERY_AUDIO STM32H747I_DISCOVERY_AUDIO
Jerome Coutant 0:146cf26a9bbb 129 * @brief This file includes the low layer driver for wm8994 Audio Codec
Jerome Coutant 0:146cf26a9bbb 130 * available on STM32H747I-DISCOVERY discovery board(MB1248).
Jerome Coutant 0:146cf26a9bbb 131 * @{
Jerome Coutant 0:146cf26a9bbb 132 */
Jerome Coutant 0:146cf26a9bbb 133
Jerome Coutant 0:146cf26a9bbb 134 /** @defgroup STM32H747I_DISCOVERY_AUDIO_Private_Variables Private Variables
Jerome Coutant 0:146cf26a9bbb 135 * @{
Jerome Coutant 0:146cf26a9bbb 136 */
Jerome Coutant 0:146cf26a9bbb 137 /* PLAY */
Jerome Coutant 0:146cf26a9bbb 138 AUDIO_DrvTypeDef *audio_drv;
Jerome Coutant 0:146cf26a9bbb 139 SAI_HandleTypeDef haudio_out_sai;
Jerome Coutant 0:146cf26a9bbb 140 SAI_HandleTypeDef haudio_in_sai;
Jerome Coutant 0:146cf26a9bbb 141
Jerome Coutant 0:146cf26a9bbb 142 /* RECORD */
Jerome Coutant 0:146cf26a9bbb 143 AUDIOIN_ContextTypeDef hAudioIn;
Jerome Coutant 0:146cf26a9bbb 144
Jerome Coutant 0:146cf26a9bbb 145
Jerome Coutant 0:146cf26a9bbb 146
Jerome Coutant 0:146cf26a9bbb 147 /* Audio in Volume value */
Jerome Coutant 0:146cf26a9bbb 148 __IO uint16_t AudioInVolume = DEFAULT_AUDIO_IN_VOLUME;
Jerome Coutant 0:146cf26a9bbb 149
Jerome Coutant 0:146cf26a9bbb 150 /* PDM filters params */
Jerome Coutant 1:9716849a8de8 151 // PDM_Filter_Handler_t PDM_FilterHandler[2];
Jerome Coutant 1:9716849a8de8 152 // PDM_Filter_Config_t PDM_FilterConfig[2];
Jerome Coutant 0:146cf26a9bbb 153
Jerome Coutant 0:146cf26a9bbb 154 /**
Jerome Coutant 0:146cf26a9bbb 155 * @}
Jerome Coutant 0:146cf26a9bbb 156 */
Jerome Coutant 0:146cf26a9bbb 157
Jerome Coutant 0:146cf26a9bbb 158 /** @defgroup STM32H747I_DISCOVERY_AUDIO_Private_Function_Prototypes Private FunctionPrototypes
Jerome Coutant 0:146cf26a9bbb 159 * @{
Jerome Coutant 0:146cf26a9bbb 160 */
Jerome Coutant 0:146cf26a9bbb 161 static void SAIx_Out_Init(uint32_t SaiOutMode, uint32_t SlotActive, uint32_t AudioFreq);
Jerome Coutant 0:146cf26a9bbb 162 static void SAIx_Out_DeInit(SAI_HandleTypeDef *hsai);
Jerome Coutant 0:146cf26a9bbb 163 static void SAIx_In_MspInit(SAI_HandleTypeDef *hsai, void *Params);
Jerome Coutant 0:146cf26a9bbb 164 static void SAIx_In_MspDeInit(SAI_HandleTypeDef *hsai, void *Params);
Jerome Coutant 0:146cf26a9bbb 165 static void SAIx_In_Init(uint32_t SaiInMode, uint32_t SlotActive, uint32_t AudioFreq);
Jerome Coutant 0:146cf26a9bbb 166 static void SAIx_In_DeInit(SAI_HandleTypeDef *hsai);
Jerome Coutant 0:146cf26a9bbb 167
Jerome Coutant 0:146cf26a9bbb 168 /**
Jerome Coutant 0:146cf26a9bbb 169 * @}
Jerome Coutant 0:146cf26a9bbb 170 */
Jerome Coutant 0:146cf26a9bbb 171
Jerome Coutant 0:146cf26a9bbb 172 /** @defgroup STM32H747I_DISCOVERY_AUDIO_OUT_Exported_Functions OUT Exported Functions
Jerome Coutant 0:146cf26a9bbb 173 * @{
Jerome Coutant 0:146cf26a9bbb 174 */
Jerome Coutant 0:146cf26a9bbb 175
Jerome Coutant 0:146cf26a9bbb 176 /**
Jerome Coutant 0:146cf26a9bbb 177 * @brief Configures the audio Out peripheral.
Jerome Coutant 0:146cf26a9bbb 178 * @param OutputDevice: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
Jerome Coutant 0:146cf26a9bbb 179 * or OUTPUT_DEVICE_BOTH.
Jerome Coutant 0:146cf26a9bbb 180 * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max))
Jerome Coutant 0:146cf26a9bbb 181 * @param AudioFreq: Audio frequency used to play the audio stream.
Jerome Coutant 0:146cf26a9bbb 182 * @retval AUDIO_OK if correct communication, else wrong communication
Jerome Coutant 0:146cf26a9bbb 183 */
Jerome Coutant 0:146cf26a9bbb 184 uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq)
Jerome Coutant 0:146cf26a9bbb 185 {
Jerome Coutant 0:146cf26a9bbb 186 uint8_t ret = AUDIO_ERROR;
Jerome Coutant 0:146cf26a9bbb 187 uint32_t deviceid = 0x00;
Jerome Coutant 0:146cf26a9bbb 188 uint32_t slot_active;
Jerome Coutant 0:146cf26a9bbb 189
Jerome Coutant 0:146cf26a9bbb 190 /* Initialize SAI1 sub_block A as MASTER TX */
Jerome Coutant 0:146cf26a9bbb 191 haudio_out_sai.Instance = AUDIO_OUT_SAIx;
Jerome Coutant 0:146cf26a9bbb 192
Jerome Coutant 0:146cf26a9bbb 193 /* Disable SAI */
Jerome Coutant 0:146cf26a9bbb 194 SAIx_Out_DeInit(&haudio_out_sai);
Jerome Coutant 0:146cf26a9bbb 195
Jerome Coutant 0:146cf26a9bbb 196 /* PLL clock is set depending by the AudioFreq (44.1khz vs 48khz groups) */
Jerome Coutant 0:146cf26a9bbb 197 BSP_AUDIO_OUT_ClockConfig(&haudio_out_sai, AudioFreq, NULL);
Jerome Coutant 0:146cf26a9bbb 198
Jerome Coutant 0:146cf26a9bbb 199 /* SAI data transfer preparation:
Jerome Coutant 0:146cf26a9bbb 200 Prepare the Media to be used for the audio transfer from memory to SAI peripheral */
Jerome Coutant 0:146cf26a9bbb 201
Jerome Coutant 0:146cf26a9bbb 202 if(HAL_SAI_GetState(&haudio_out_sai) == HAL_SAI_STATE_RESET)
Jerome Coutant 0:146cf26a9bbb 203 {
Jerome Coutant 0:146cf26a9bbb 204 /* Init the SAI MSP: this __weak function can be redefined by the application*/
Jerome Coutant 0:146cf26a9bbb 205 BSP_AUDIO_OUT_MspInit(&haudio_out_sai, NULL);
Jerome Coutant 0:146cf26a9bbb 206 }
Jerome Coutant 0:146cf26a9bbb 207
Jerome Coutant 0:146cf26a9bbb 208 /* Init SAI as master RX output */
Jerome Coutant 0:146cf26a9bbb 209 slot_active = CODEC_AUDIOFRAME_SLOT_0123;
Jerome Coutant 0:146cf26a9bbb 210 SAIx_Out_Init(SAI_MODEMASTER_TX, slot_active, AudioFreq);
Jerome Coutant 0:146cf26a9bbb 211
Jerome Coutant 0:146cf26a9bbb 212 /* wm8994 codec initialization */
Jerome Coutant 0:146cf26a9bbb 213 deviceid = wm8994_drv.ReadID(AUDIO_I2C_ADDRESS);
Jerome Coutant 0:146cf26a9bbb 214
Jerome Coutant 0:146cf26a9bbb 215 if((deviceid) == WM8994_ID)
Jerome Coutant 0:146cf26a9bbb 216 {
Jerome Coutant 0:146cf26a9bbb 217 /* Reset the Codec Registers */
Jerome Coutant 0:146cf26a9bbb 218 wm8994_drv.Reset(AUDIO_I2C_ADDRESS);
Jerome Coutant 0:146cf26a9bbb 219 /* Initialize the audio driver structure */
Jerome Coutant 0:146cf26a9bbb 220 audio_drv = &wm8994_drv;
Jerome Coutant 0:146cf26a9bbb 221 ret = AUDIO_OK;
Jerome Coutant 0:146cf26a9bbb 222 }
Jerome Coutant 0:146cf26a9bbb 223 else
Jerome Coutant 0:146cf26a9bbb 224 {
Jerome Coutant 0:146cf26a9bbb 225 ret = AUDIO_ERROR;
Jerome Coutant 0:146cf26a9bbb 226 }
Jerome Coutant 0:146cf26a9bbb 227
Jerome Coutant 0:146cf26a9bbb 228 if(ret == AUDIO_OK)
Jerome Coutant 0:146cf26a9bbb 229 {
Jerome Coutant 0:146cf26a9bbb 230 /* Initialize the codec internal registers */
Jerome Coutant 0:146cf26a9bbb 231 audio_drv->Init(AUDIO_I2C_ADDRESS, OutputDevice, Volume, AudioFreq);
Jerome Coutant 0:146cf26a9bbb 232 }
Jerome Coutant 0:146cf26a9bbb 233
Jerome Coutant 0:146cf26a9bbb 234 return ret;
Jerome Coutant 0:146cf26a9bbb 235 }
Jerome Coutant 0:146cf26a9bbb 236
Jerome Coutant 0:146cf26a9bbb 237 /**
Jerome Coutant 0:146cf26a9bbb 238 * @brief Starts playing audio stream from a data buffer for a determined size.
Jerome Coutant 0:146cf26a9bbb 239 * @param pBuffer: Pointer to the buffer
Jerome Coutant 0:146cf26a9bbb 240 * @param Size: Number of audio data BYTES.
Jerome Coutant 0:146cf26a9bbb 241 * @retval AUDIO_OK if correct communication, else wrong communication
Jerome Coutant 0:146cf26a9bbb 242 */
Jerome Coutant 0:146cf26a9bbb 243 uint8_t BSP_AUDIO_OUT_Play(uint16_t* pBuffer, uint32_t Size)
Jerome Coutant 0:146cf26a9bbb 244 {
Jerome Coutant 0:146cf26a9bbb 245 /* Call the audio Codec Play function */
Jerome Coutant 0:146cf26a9bbb 246 if(audio_drv->Play(AUDIO_I2C_ADDRESS, pBuffer, Size) != 0)
Jerome Coutant 0:146cf26a9bbb 247 {
Jerome Coutant 0:146cf26a9bbb 248 return AUDIO_ERROR;
Jerome Coutant 0:146cf26a9bbb 249 }
Jerome Coutant 0:146cf26a9bbb 250 else
Jerome Coutant 0:146cf26a9bbb 251 {
Jerome Coutant 0:146cf26a9bbb 252 /* Update the Media layer and enable it for play */
Jerome Coutant 0:146cf26a9bbb 253 HAL_SAI_Transmit_DMA(&haudio_out_sai, (uint8_t*) pBuffer, DMA_MAX(Size / AUDIODATA_SIZE));
Jerome Coutant 0:146cf26a9bbb 254
Jerome Coutant 0:146cf26a9bbb 255 return AUDIO_OK;
Jerome Coutant 0:146cf26a9bbb 256 }
Jerome Coutant 0:146cf26a9bbb 257 }
Jerome Coutant 0:146cf26a9bbb 258
Jerome Coutant 0:146cf26a9bbb 259 /**
Jerome Coutant 0:146cf26a9bbb 260 * @brief Sends n-Bytes on the SAI interface.
Jerome Coutant 0:146cf26a9bbb 261 * @param pData: pointer on data address
Jerome Coutant 0:146cf26a9bbb 262 * @param Size: number of data to be written
Jerome Coutant 0:146cf26a9bbb 263 * @retval None
Jerome Coutant 0:146cf26a9bbb 264 */
Jerome Coutant 0:146cf26a9bbb 265 void BSP_AUDIO_OUT_ChangeBuffer(uint16_t *pData, uint16_t Size)
Jerome Coutant 0:146cf26a9bbb 266 {
Jerome Coutant 0:146cf26a9bbb 267 HAL_SAI_Transmit_DMA(&haudio_out_sai, (uint8_t*) pData, Size);
Jerome Coutant 0:146cf26a9bbb 268 }
Jerome Coutant 0:146cf26a9bbb 269
Jerome Coutant 0:146cf26a9bbb 270 /**
Jerome Coutant 0:146cf26a9bbb 271 * @brief This function Pauses the audio file stream. In case
Jerome Coutant 0:146cf26a9bbb 272 * of using DMA, the DMA Pause feature is used.
Jerome Coutant 0:146cf26a9bbb 273 * @warning When calling BSP_AUDIO_OUT_Pause() function for pause, only
Jerome Coutant 0:146cf26a9bbb 274 * BSP_AUDIO_OUT_Resume() function should be called for resume (use of BSP_AUDIO_OUT_Play()
Jerome Coutant 0:146cf26a9bbb 275 * function for resume could lead to unexpected behaviour).
Jerome Coutant 0:146cf26a9bbb 276 * @retval AUDIO_OK if correct communication, else wrong communication
Jerome Coutant 0:146cf26a9bbb 277 */
Jerome Coutant 0:146cf26a9bbb 278 uint8_t BSP_AUDIO_OUT_Pause(void)
Jerome Coutant 0:146cf26a9bbb 279 {
Jerome Coutant 0:146cf26a9bbb 280 /* Call the Audio Codec Pause/Resume function */
Jerome Coutant 0:146cf26a9bbb 281 if(audio_drv->Pause(AUDIO_I2C_ADDRESS) != 0)
Jerome Coutant 0:146cf26a9bbb 282 {
Jerome Coutant 0:146cf26a9bbb 283 return AUDIO_ERROR;
Jerome Coutant 0:146cf26a9bbb 284 }
Jerome Coutant 0:146cf26a9bbb 285 else
Jerome Coutant 0:146cf26a9bbb 286 {
Jerome Coutant 0:146cf26a9bbb 287 /* Call the Media layer pause function */
Jerome Coutant 0:146cf26a9bbb 288 HAL_SAI_DMAPause(&haudio_out_sai);
Jerome Coutant 0:146cf26a9bbb 289
Jerome Coutant 0:146cf26a9bbb 290 /* Return AUDIO_OK when all operations are correctly done */
Jerome Coutant 0:146cf26a9bbb 291 return AUDIO_OK;
Jerome Coutant 0:146cf26a9bbb 292 }
Jerome Coutant 0:146cf26a9bbb 293 }
Jerome Coutant 0:146cf26a9bbb 294
Jerome Coutant 0:146cf26a9bbb 295 /**
Jerome Coutant 0:146cf26a9bbb 296 * @brief Resumes the audio file stream.
Jerome Coutant 0:146cf26a9bbb 297 * @warning When calling BSP_AUDIO_OUT_Pause() function for pause, only
Jerome Coutant 0:146cf26a9bbb 298 * BSP_AUDIO_OUT_Resume() function should be called for resume (use of BSP_AUDIO_OUT_Play()
Jerome Coutant 0:146cf26a9bbb 299 * function for resume could lead to unexpected behaviour).
Jerome Coutant 0:146cf26a9bbb 300 * @retval AUDIO_OK if correct communication, else wrong communication
Jerome Coutant 0:146cf26a9bbb 301 */
Jerome Coutant 0:146cf26a9bbb 302 uint8_t BSP_AUDIO_OUT_Resume(void)
Jerome Coutant 0:146cf26a9bbb 303 {
Jerome Coutant 0:146cf26a9bbb 304 /* Call the Audio Codec Pause/Resume function */
Jerome Coutant 0:146cf26a9bbb 305 if(audio_drv->Resume(AUDIO_I2C_ADDRESS) != 0)
Jerome Coutant 0:146cf26a9bbb 306 {
Jerome Coutant 0:146cf26a9bbb 307 return AUDIO_ERROR;
Jerome Coutant 0:146cf26a9bbb 308 }
Jerome Coutant 0:146cf26a9bbb 309 else
Jerome Coutant 0:146cf26a9bbb 310 {
Jerome Coutant 0:146cf26a9bbb 311 /* Call the Media layer pause/resume function */
Jerome Coutant 0:146cf26a9bbb 312 HAL_SAI_DMAResume(&haudio_out_sai);
Jerome Coutant 0:146cf26a9bbb 313
Jerome Coutant 0:146cf26a9bbb 314 /* Return AUDIO_OK when all operations are correctly done */
Jerome Coutant 0:146cf26a9bbb 315 return AUDIO_OK;
Jerome Coutant 0:146cf26a9bbb 316 }
Jerome Coutant 0:146cf26a9bbb 317 }
Jerome Coutant 0:146cf26a9bbb 318
Jerome Coutant 0:146cf26a9bbb 319 /**
Jerome Coutant 0:146cf26a9bbb 320 * @brief Stops audio playing and Power down the Audio Codec.
Jerome Coutant 0:146cf26a9bbb 321 * @param Option: could be one of the following parameters
Jerome Coutant 0:146cf26a9bbb 322 * - CODEC_PDWN_SW: for software power off (by writing registers).
Jerome Coutant 0:146cf26a9bbb 323 * Then no need to reconfigure the Codec after power on.
Jerome Coutant 0:146cf26a9bbb 324 * - CODEC_PDWN_HW: completely shut down the codec (physically).
Jerome Coutant 0:146cf26a9bbb 325 * Then need to reconfigure the Codec after power on.
Jerome Coutant 0:146cf26a9bbb 326 * @retval AUDIO_OK if correct communication, else wrong communication
Jerome Coutant 0:146cf26a9bbb 327 */
Jerome Coutant 0:146cf26a9bbb 328 uint8_t BSP_AUDIO_OUT_Stop(uint32_t Option)
Jerome Coutant 0:146cf26a9bbb 329 {
Jerome Coutant 0:146cf26a9bbb 330 /* Call the Media layer stop function */
Jerome Coutant 0:146cf26a9bbb 331 HAL_SAI_DMAStop(&haudio_out_sai);
Jerome Coutant 0:146cf26a9bbb 332
Jerome Coutant 0:146cf26a9bbb 333 /* Call Audio Codec Stop function */
Jerome Coutant 0:146cf26a9bbb 334 if(audio_drv->Stop(AUDIO_I2C_ADDRESS, Option) != 0)
Jerome Coutant 0:146cf26a9bbb 335 {
Jerome Coutant 0:146cf26a9bbb 336 return AUDIO_ERROR;
Jerome Coutant 0:146cf26a9bbb 337 }
Jerome Coutant 0:146cf26a9bbb 338 else
Jerome Coutant 0:146cf26a9bbb 339 {
Jerome Coutant 0:146cf26a9bbb 340 if(Option == CODEC_PDWN_HW)
Jerome Coutant 0:146cf26a9bbb 341 {
Jerome Coutant 0:146cf26a9bbb 342 /* Wait at least 100us */
Jerome Coutant 0:146cf26a9bbb 343 HAL_Delay(1);
Jerome Coutant 0:146cf26a9bbb 344 }
Jerome Coutant 0:146cf26a9bbb 345 /* Return AUDIO_OK when all operations are correctly done */
Jerome Coutant 0:146cf26a9bbb 346 return AUDIO_OK;
Jerome Coutant 0:146cf26a9bbb 347 }
Jerome Coutant 0:146cf26a9bbb 348 }
Jerome Coutant 0:146cf26a9bbb 349
Jerome Coutant 0:146cf26a9bbb 350 /**
Jerome Coutant 0:146cf26a9bbb 351 * @brief Controls the current audio volume level.
Jerome Coutant 0:146cf26a9bbb 352 * @param Volume: Volume level to be set in percentage from 0% to 100% (0 for
Jerome Coutant 0:146cf26a9bbb 353 * Mute and 100 for Max volume level).
Jerome Coutant 0:146cf26a9bbb 354 * @retval AUDIO_OK if correct communication, else wrong communication
Jerome Coutant 0:146cf26a9bbb 355 */
Jerome Coutant 0:146cf26a9bbb 356 uint8_t BSP_AUDIO_OUT_SetVolume(uint8_t Volume)
Jerome Coutant 0:146cf26a9bbb 357 {
Jerome Coutant 0:146cf26a9bbb 358 /* Call the codec volume control function with converted volume value */
Jerome Coutant 0:146cf26a9bbb 359 if(audio_drv->SetVolume(AUDIO_I2C_ADDRESS, Volume) != 0)
Jerome Coutant 0:146cf26a9bbb 360 {
Jerome Coutant 0:146cf26a9bbb 361 return AUDIO_ERROR;
Jerome Coutant 0:146cf26a9bbb 362 }
Jerome Coutant 0:146cf26a9bbb 363 else
Jerome Coutant 0:146cf26a9bbb 364 {
Jerome Coutant 0:146cf26a9bbb 365 /* Return AUDIO_OK when all operations are correctly done */
Jerome Coutant 0:146cf26a9bbb 366 return AUDIO_OK;
Jerome Coutant 0:146cf26a9bbb 367 }
Jerome Coutant 0:146cf26a9bbb 368 }
Jerome Coutant 0:146cf26a9bbb 369
Jerome Coutant 0:146cf26a9bbb 370 /**
Jerome Coutant 0:146cf26a9bbb 371 * @brief Enables or disables the MUTE mode by software
Jerome Coutant 0:146cf26a9bbb 372 * @param Cmd: Could be AUDIO_MUTE_ON to mute sound or AUDIO_MUTE_OFF to
Jerome Coutant 0:146cf26a9bbb 373 * unmute the codec and restore previous volume level.
Jerome Coutant 0:146cf26a9bbb 374 * @retval AUDIO_OK if correct communication, else wrong communication
Jerome Coutant 0:146cf26a9bbb 375 */
Jerome Coutant 0:146cf26a9bbb 376 uint8_t BSP_AUDIO_OUT_SetMute(uint32_t Cmd)
Jerome Coutant 0:146cf26a9bbb 377 {
Jerome Coutant 0:146cf26a9bbb 378 /* Call the Codec Mute function */
Jerome Coutant 0:146cf26a9bbb 379 if(audio_drv->SetMute(AUDIO_I2C_ADDRESS, Cmd) != 0)
Jerome Coutant 0:146cf26a9bbb 380 {
Jerome Coutant 0:146cf26a9bbb 381 return AUDIO_ERROR;
Jerome Coutant 0:146cf26a9bbb 382 }
Jerome Coutant 0:146cf26a9bbb 383 else
Jerome Coutant 0:146cf26a9bbb 384 {
Jerome Coutant 0:146cf26a9bbb 385 /* Return AUDIO_OK when all operations are correctly done */
Jerome Coutant 0:146cf26a9bbb 386 return AUDIO_OK;
Jerome Coutant 0:146cf26a9bbb 387 }
Jerome Coutant 0:146cf26a9bbb 388 }
Jerome Coutant 0:146cf26a9bbb 389
Jerome Coutant 0:146cf26a9bbb 390 /**
Jerome Coutant 0:146cf26a9bbb 391 * @brief Switch dynamically (while audio file is played) the output target
Jerome Coutant 0:146cf26a9bbb 392 * (speaker or headphone).
Jerome Coutant 0:146cf26a9bbb 393 * @param Output: The audio output target: OUTPUT_DEVICE_SPEAKER,
Jerome Coutant 0:146cf26a9bbb 394 * OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH
Jerome Coutant 0:146cf26a9bbb 395 * @retval AUDIO_OK if correct communication, else wrong communication
Jerome Coutant 0:146cf26a9bbb 396 */
Jerome Coutant 0:146cf26a9bbb 397 uint8_t BSP_AUDIO_OUT_SetOutputMode(uint8_t Output)
Jerome Coutant 0:146cf26a9bbb 398 {
Jerome Coutant 0:146cf26a9bbb 399 /* Call the Codec output device function */
Jerome Coutant 0:146cf26a9bbb 400 if(audio_drv->SetOutputMode(AUDIO_I2C_ADDRESS, Output) != 0)
Jerome Coutant 0:146cf26a9bbb 401 {
Jerome Coutant 0:146cf26a9bbb 402 return AUDIO_ERROR;
Jerome Coutant 0:146cf26a9bbb 403 }
Jerome Coutant 0:146cf26a9bbb 404 else
Jerome Coutant 0:146cf26a9bbb 405 {
Jerome Coutant 0:146cf26a9bbb 406 /* Return AUDIO_OK when all operations are correctly done */
Jerome Coutant 0:146cf26a9bbb 407 return AUDIO_OK;
Jerome Coutant 0:146cf26a9bbb 408 }
Jerome Coutant 0:146cf26a9bbb 409 }
Jerome Coutant 0:146cf26a9bbb 410
Jerome Coutant 0:146cf26a9bbb 411 /**
Jerome Coutant 0:146cf26a9bbb 412 * @brief Updates the audio frequency.
Jerome Coutant 0:146cf26a9bbb 413 * @param AudioFreq: Audio frequency used to play the audio stream.
Jerome Coutant 0:146cf26a9bbb 414 * @note This API should be called after the BSP_AUDIO_OUT_Init() to adjust the
Jerome Coutant 0:146cf26a9bbb 415 * audio frequency.
Jerome Coutant 0:146cf26a9bbb 416 * @retval None
Jerome Coutant 0:146cf26a9bbb 417 */
Jerome Coutant 0:146cf26a9bbb 418 void BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq)
Jerome Coutant 0:146cf26a9bbb 419 {
Jerome Coutant 0:146cf26a9bbb 420 /* PLL clock is set depending by the AudioFreq (44.1khz vs 48khz groups) */
Jerome Coutant 0:146cf26a9bbb 421 BSP_AUDIO_OUT_ClockConfig(&haudio_out_sai, AudioFreq, NULL);
Jerome Coutant 0:146cf26a9bbb 422
Jerome Coutant 0:146cf26a9bbb 423 /* Disable SAI peripheral to allow access to SAI internal registers */
Jerome Coutant 0:146cf26a9bbb 424 __HAL_SAI_DISABLE(&haudio_out_sai);
Jerome Coutant 0:146cf26a9bbb 425
Jerome Coutant 0:146cf26a9bbb 426 /* Update the SAI audio frequency configuration */
Jerome Coutant 0:146cf26a9bbb 427 haudio_out_sai.Init.AudioFrequency = AudioFreq;
Jerome Coutant 0:146cf26a9bbb 428 HAL_SAI_Init(&haudio_out_sai);
Jerome Coutant 0:146cf26a9bbb 429
Jerome Coutant 0:146cf26a9bbb 430 /* Enable SAI peripheral to generate MCLK */
Jerome Coutant 0:146cf26a9bbb 431 __HAL_SAI_ENABLE(&haudio_out_sai);
Jerome Coutant 0:146cf26a9bbb 432 }
Jerome Coutant 0:146cf26a9bbb 433
Jerome Coutant 0:146cf26a9bbb 434 /**
Jerome Coutant 0:146cf26a9bbb 435 * @brief Updates the Audio frame slot configuration.
Jerome Coutant 0:146cf26a9bbb 436 * @param AudioFrameSlot: specifies the audio Frame slot
Jerome Coutant 0:146cf26a9bbb 437 * @note This API should be called after the BSP_AUDIO_OUT_Init() to adjust the
Jerome Coutant 0:146cf26a9bbb 438 * audio frame slot.
Jerome Coutant 0:146cf26a9bbb 439 * @retval None
Jerome Coutant 0:146cf26a9bbb 440 */
Jerome Coutant 0:146cf26a9bbb 441 void BSP_AUDIO_OUT_SetAudioFrameSlot(uint32_t AudioFrameSlot)
Jerome Coutant 0:146cf26a9bbb 442 {
Jerome Coutant 0:146cf26a9bbb 443 /* Disable SAI peripheral to allow access to SAI internal registers */
Jerome Coutant 0:146cf26a9bbb 444 __HAL_SAI_DISABLE(&haudio_out_sai);
Jerome Coutant 0:146cf26a9bbb 445
Jerome Coutant 0:146cf26a9bbb 446 /* Update the SAI audio frame slot configuration */
Jerome Coutant 0:146cf26a9bbb 447 haudio_out_sai.SlotInit.SlotActive = AudioFrameSlot;
Jerome Coutant 0:146cf26a9bbb 448 HAL_SAI_Init(&haudio_out_sai);
Jerome Coutant 0:146cf26a9bbb 449
Jerome Coutant 0:146cf26a9bbb 450 /* Enable SAI peripheral to generate MCLK */
Jerome Coutant 0:146cf26a9bbb 451 __HAL_SAI_ENABLE(&haudio_out_sai);
Jerome Coutant 0:146cf26a9bbb 452 }
Jerome Coutant 0:146cf26a9bbb 453
Jerome Coutant 0:146cf26a9bbb 454 /**
Jerome Coutant 0:146cf26a9bbb 455 * @brief De-initializes the audio out peripheral.
Jerome Coutant 0:146cf26a9bbb 456 * @retval None
Jerome Coutant 0:146cf26a9bbb 457 */
Jerome Coutant 0:146cf26a9bbb 458 void BSP_AUDIO_OUT_DeInit(void)
Jerome Coutant 0:146cf26a9bbb 459 {
Jerome Coutant 0:146cf26a9bbb 460 SAIx_Out_DeInit(&haudio_out_sai);
Jerome Coutant 0:146cf26a9bbb 461 /* DeInit the SAI MSP : this __weak function can be rewritten by the application */
Jerome Coutant 0:146cf26a9bbb 462 BSP_AUDIO_OUT_MspDeInit(&haudio_out_sai, NULL);
Jerome Coutant 0:146cf26a9bbb 463 }
Jerome Coutant 0:146cf26a9bbb 464
Jerome Coutant 0:146cf26a9bbb 465 /**
Jerome Coutant 0:146cf26a9bbb 466 * @brief Manages the DMA full Transfer complete event.
Jerome Coutant 0:146cf26a9bbb 467 * @retval None
Jerome Coutant 0:146cf26a9bbb 468 */
Jerome Coutant 0:146cf26a9bbb 469 __weak void BSP_AUDIO_OUT_TransferComplete_CallBack(void)
Jerome Coutant 0:146cf26a9bbb 470 {
Jerome Coutant 0:146cf26a9bbb 471 }
Jerome Coutant 0:146cf26a9bbb 472
Jerome Coutant 0:146cf26a9bbb 473 /**
Jerome Coutant 0:146cf26a9bbb 474 * @brief Manages the DMA Half Transfer complete event.
Jerome Coutant 0:146cf26a9bbb 475 * @retval None
Jerome Coutant 0:146cf26a9bbb 476 */
Jerome Coutant 0:146cf26a9bbb 477 __weak void BSP_AUDIO_OUT_HalfTransfer_CallBack(void)
Jerome Coutant 0:146cf26a9bbb 478 {
Jerome Coutant 0:146cf26a9bbb 479 }
Jerome Coutant 0:146cf26a9bbb 480
Jerome Coutant 0:146cf26a9bbb 481 /**
Jerome Coutant 0:146cf26a9bbb 482 * @brief Manages the DMA FIFO error event.
Jerome Coutant 0:146cf26a9bbb 483 * @retval None
Jerome Coutant 0:146cf26a9bbb 484 */
Jerome Coutant 0:146cf26a9bbb 485 __weak void BSP_AUDIO_OUT_Error_CallBack(void)
Jerome Coutant 0:146cf26a9bbb 486 {
Jerome Coutant 0:146cf26a9bbb 487 }
Jerome Coutant 0:146cf26a9bbb 488
Jerome Coutant 0:146cf26a9bbb 489 /**
Jerome Coutant 0:146cf26a9bbb 490 * @brief Initializes BSP_AUDIO_OUT MSP.
Jerome Coutant 0:146cf26a9bbb 491 * @param hsai: SAI handle
Jerome Coutant 0:146cf26a9bbb 492 * @param Params: pointer on additional configuration parameters, can be NULL.
Jerome Coutant 0:146cf26a9bbb 493 * @retval None
Jerome Coutant 0:146cf26a9bbb 494 */
Jerome Coutant 0:146cf26a9bbb 495 __weak void BSP_AUDIO_OUT_MspInit(SAI_HandleTypeDef *hsai, void *Params)
Jerome Coutant 0:146cf26a9bbb 496 {
Jerome Coutant 0:146cf26a9bbb 497 static DMA_HandleTypeDef hdma_sai_tx;
Jerome Coutant 0:146cf26a9bbb 498 GPIO_InitTypeDef gpio_init_structure;
Jerome Coutant 0:146cf26a9bbb 499
Jerome Coutant 0:146cf26a9bbb 500 /* Enable SAI clock */
Jerome Coutant 0:146cf26a9bbb 501 AUDIO_OUT_SAIx_CLK_ENABLE();
Jerome Coutant 0:146cf26a9bbb 502
Jerome Coutant 0:146cf26a9bbb 503 /* CODEC_SAI pins configuration: FS, SCK and SD pins */
Jerome Coutant 0:146cf26a9bbb 504 /* Enable FS, SCK and SD clocks */
Jerome Coutant 0:146cf26a9bbb 505 AUDIO_OUT_SAIx_SD_FS_CLK_ENABLE();
Jerome Coutant 0:146cf26a9bbb 506 /* Enable FS, SCK and SD pins */
Jerome Coutant 0:146cf26a9bbb 507 gpio_init_structure.Pin = AUDIO_OUT_SAIx_FS_PIN | AUDIO_OUT_SAIx_SCK_PIN | AUDIO_OUT_SAIx_SD_PIN;
Jerome Coutant 0:146cf26a9bbb 508 gpio_init_structure.Mode = GPIO_MODE_AF_PP;
Jerome Coutant 0:146cf26a9bbb 509 gpio_init_structure.Pull = GPIO_NOPULL;
Jerome Coutant 0:146cf26a9bbb 510 gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
Jerome Coutant 0:146cf26a9bbb 511 gpio_init_structure.Alternate = AUDIO_OUT_SAIx_AF;
Jerome Coutant 0:146cf26a9bbb 512 HAL_GPIO_Init(AUDIO_OUT_SAIx_SD_FS_SCK_GPIO_PORT, &gpio_init_structure);
Jerome Coutant 0:146cf26a9bbb 513
Jerome Coutant 0:146cf26a9bbb 514 /* Enable MCLK clock */
Jerome Coutant 0:146cf26a9bbb 515 AUDIO_OUT_SAIx_MCLK_ENABLE();
Jerome Coutant 0:146cf26a9bbb 516 /* Enable MCLK pin */
Jerome Coutant 0:146cf26a9bbb 517 gpio_init_structure.Pin = AUDIO_OUT_SAIx_MCLK_PIN;
Jerome Coutant 0:146cf26a9bbb 518 HAL_GPIO_Init(AUDIO_OUT_SAIx_MCLK_GPIO_PORT, &gpio_init_structure);
Jerome Coutant 0:146cf26a9bbb 519
Jerome Coutant 0:146cf26a9bbb 520 /* Enable the DMA clock */
Jerome Coutant 0:146cf26a9bbb 521 AUDIO_OUT_SAIx_DMAx_CLK_ENABLE();
Jerome Coutant 0:146cf26a9bbb 522
Jerome Coutant 0:146cf26a9bbb 523 if(hsai->Instance == AUDIO_OUT_SAIx)
Jerome Coutant 0:146cf26a9bbb 524 {
Jerome Coutant 0:146cf26a9bbb 525 /* Configure the hdma_saiTx handle parameters */
Jerome Coutant 0:146cf26a9bbb 526 hdma_sai_tx.Init.Request = AUDIO_OUT_SAIx_DMAx_REQUEST;
Jerome Coutant 0:146cf26a9bbb 527 hdma_sai_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
Jerome Coutant 0:146cf26a9bbb 528 hdma_sai_tx.Init.PeriphInc = DMA_PINC_DISABLE;
Jerome Coutant 0:146cf26a9bbb 529 hdma_sai_tx.Init.MemInc = DMA_MINC_ENABLE;
Jerome Coutant 0:146cf26a9bbb 530 hdma_sai_tx.Init.PeriphDataAlignment = AUDIO_OUT_SAIx_DMAx_PERIPH_DATA_SIZE;
Jerome Coutant 0:146cf26a9bbb 531 hdma_sai_tx.Init.MemDataAlignment = AUDIO_OUT_SAIx_DMAx_MEM_DATA_SIZE;
Jerome Coutant 0:146cf26a9bbb 532 hdma_sai_tx.Init.Mode = DMA_CIRCULAR;
Jerome Coutant 0:146cf26a9bbb 533 hdma_sai_tx.Init.Priority = DMA_PRIORITY_HIGH;
Jerome Coutant 0:146cf26a9bbb 534 hdma_sai_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
Jerome Coutant 0:146cf26a9bbb 535 hdma_sai_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
Jerome Coutant 0:146cf26a9bbb 536 hdma_sai_tx.Init.MemBurst = DMA_MBURST_SINGLE;
Jerome Coutant 0:146cf26a9bbb 537 hdma_sai_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
Jerome Coutant 0:146cf26a9bbb 538
Jerome Coutant 0:146cf26a9bbb 539 hdma_sai_tx.Instance = AUDIO_OUT_SAIx_DMAx_STREAM;
Jerome Coutant 0:146cf26a9bbb 540
Jerome Coutant 0:146cf26a9bbb 541 /* Associate the DMA handle */
Jerome Coutant 0:146cf26a9bbb 542 __HAL_LINKDMA(hsai, hdmatx, hdma_sai_tx);
Jerome Coutant 0:146cf26a9bbb 543
Jerome Coutant 0:146cf26a9bbb 544 /* Deinitialize the Stream for new transfer */
Jerome Coutant 0:146cf26a9bbb 545 HAL_DMA_DeInit(&hdma_sai_tx);
Jerome Coutant 0:146cf26a9bbb 546
Jerome Coutant 0:146cf26a9bbb 547 /* Configure the DMA Stream */
Jerome Coutant 0:146cf26a9bbb 548 HAL_DMA_Init(&hdma_sai_tx);
Jerome Coutant 0:146cf26a9bbb 549 }
Jerome Coutant 0:146cf26a9bbb 550
Jerome Coutant 0:146cf26a9bbb 551 /* SAI DMA IRQ Channel configuration */
Jerome Coutant 0:146cf26a9bbb 552 HAL_NVIC_SetPriority(AUDIO_OUT_SAIx_DMAx_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0);
Jerome Coutant 0:146cf26a9bbb 553 HAL_NVIC_EnableIRQ(AUDIO_OUT_SAIx_DMAx_IRQ);
Jerome Coutant 0:146cf26a9bbb 554 }
Jerome Coutant 0:146cf26a9bbb 555
Jerome Coutant 0:146cf26a9bbb 556 /**
Jerome Coutant 0:146cf26a9bbb 557 * @brief Deinitializes SAI MSP.
Jerome Coutant 0:146cf26a9bbb 558 * @param hsai: SAI handle
Jerome Coutant 0:146cf26a9bbb 559 * @param Params: pointer on additional configuration parameters, can be NULL.
Jerome Coutant 0:146cf26a9bbb 560 * @retval None
Jerome Coutant 0:146cf26a9bbb 561 */
Jerome Coutant 0:146cf26a9bbb 562 __weak void BSP_AUDIO_OUT_MspDeInit(SAI_HandleTypeDef *hsai, void *Params)
Jerome Coutant 0:146cf26a9bbb 563 {
Jerome Coutant 0:146cf26a9bbb 564 GPIO_InitTypeDef gpio_init_structure;
Jerome Coutant 0:146cf26a9bbb 565
Jerome Coutant 0:146cf26a9bbb 566 /* SAI DMA IRQ Channel deactivation */
Jerome Coutant 0:146cf26a9bbb 567 HAL_NVIC_DisableIRQ(AUDIO_OUT_SAIx_DMAx_IRQ);
Jerome Coutant 0:146cf26a9bbb 568
Jerome Coutant 0:146cf26a9bbb 569 if(hsai->Instance == AUDIO_OUT_SAIx)
Jerome Coutant 0:146cf26a9bbb 570 {
Jerome Coutant 0:146cf26a9bbb 571 /* Deinitialize the DMA stream */
Jerome Coutant 0:146cf26a9bbb 572 HAL_DMA_DeInit(hsai->hdmatx);
Jerome Coutant 0:146cf26a9bbb 573 }
Jerome Coutant 0:146cf26a9bbb 574
Jerome Coutant 0:146cf26a9bbb 575 /* Disable SAI peripheral */
Jerome Coutant 0:146cf26a9bbb 576 __HAL_SAI_DISABLE(hsai);
Jerome Coutant 0:146cf26a9bbb 577
Jerome Coutant 0:146cf26a9bbb 578 /* Deactivates CODEC_SAI pins FS, SCK, MCK and SD by putting them in input mode */
Jerome Coutant 0:146cf26a9bbb 579 gpio_init_structure.Pin = AUDIO_OUT_SAIx_FS_PIN | AUDIO_OUT_SAIx_SCK_PIN | AUDIO_OUT_SAIx_SD_PIN;
Jerome Coutant 0:146cf26a9bbb 580 HAL_GPIO_DeInit(AUDIO_OUT_SAIx_SD_FS_SCK_GPIO_PORT, gpio_init_structure.Pin);
Jerome Coutant 0:146cf26a9bbb 581
Jerome Coutant 0:146cf26a9bbb 582 gpio_init_structure.Pin = AUDIO_OUT_SAIx_MCLK_PIN;
Jerome Coutant 0:146cf26a9bbb 583 HAL_GPIO_DeInit(AUDIO_OUT_SAIx_MCLK_GPIO_PORT, gpio_init_structure.Pin);
Jerome Coutant 0:146cf26a9bbb 584
Jerome Coutant 0:146cf26a9bbb 585 /* Disable SAI clock */
Jerome Coutant 0:146cf26a9bbb 586 AUDIO_OUT_SAIx_CLK_DISABLE();
Jerome Coutant 0:146cf26a9bbb 587
Jerome Coutant 0:146cf26a9bbb 588 /* GPIO pins clock and DMA clock can be shut down in the applic
Jerome Coutant 0:146cf26a9bbb 589 by surcharging this __weak function */
Jerome Coutant 0:146cf26a9bbb 590 }
Jerome Coutant 0:146cf26a9bbb 591
Jerome Coutant 0:146cf26a9bbb 592 /**
Jerome Coutant 0:146cf26a9bbb 593 * @brief Clock Config.
Jerome Coutant 0:146cf26a9bbb 594 * @param hsai: might be required to set audio peripheral predivider if any.
Jerome Coutant 0:146cf26a9bbb 595 * @param AudioFreq: Audio frequency used to play the audio stream.
Jerome Coutant 0:146cf26a9bbb 596 * @param Params: pointer on additional configuration parameters, can be NULL.
Jerome Coutant 0:146cf26a9bbb 597 * @note This API is called by BSP_AUDIO_OUT_Init() and BSP_AUDIO_OUT_SetFrequency()
Jerome Coutant 0:146cf26a9bbb 598 * Being __weak it can be overwritten by the application
Jerome Coutant 0:146cf26a9bbb 599 * @retval None
Jerome Coutant 0:146cf26a9bbb 600 */
Jerome Coutant 0:146cf26a9bbb 601 __weak void BSP_AUDIO_OUT_ClockConfig(SAI_HandleTypeDef *hsai, uint32_t AudioFreq, void *Params)
Jerome Coutant 0:146cf26a9bbb 602 {
Jerome Coutant 0:146cf26a9bbb 603 RCC_PeriphCLKInitTypeDef rcc_ex_clk_init_struct;
Jerome Coutant 0:146cf26a9bbb 604
Jerome Coutant 0:146cf26a9bbb 605 HAL_RCCEx_GetPeriphCLKConfig(&rcc_ex_clk_init_struct);
Jerome Coutant 0:146cf26a9bbb 606
Jerome Coutant 0:146cf26a9bbb 607 /* Set the PLL configuration according to the audio frequency */
Jerome Coutant 0:146cf26a9bbb 608 if((AudioFreq == AUDIO_FREQUENCY_11K) || (AudioFreq == AUDIO_FREQUENCY_22K) || (AudioFreq == AUDIO_FREQUENCY_44K))
Jerome Coutant 0:146cf26a9bbb 609 {
Jerome Coutant 0:146cf26a9bbb 610 /* SAI clock config:
Jerome Coutant 0:146cf26a9bbb 611 PLL2_VCO Input = HSE_VALUE/PLL2M = 1 Mhz
Jerome Coutant 0:146cf26a9bbb 612 PLL2_VCO Output = PLL2_VCO Input * PLL2N = 429 Mhz
Jerome Coutant 0:146cf26a9bbb 613 SAI_CLK_x = PLL2_VCO Output/PLL2P = 429/38 = 11.289 Mhz */
Jerome Coutant 0:146cf26a9bbb 614 rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
Jerome Coutant 0:146cf26a9bbb 615 rcc_ex_clk_init_struct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLL2;
Jerome Coutant 0:146cf26a9bbb 616 rcc_ex_clk_init_struct.PLL2.PLL2P = 38;
Jerome Coutant 0:146cf26a9bbb 617 rcc_ex_clk_init_struct.PLL2.PLL2Q = 1;
Jerome Coutant 0:146cf26a9bbb 618 rcc_ex_clk_init_struct.PLL2.PLL2R = 1;
Jerome Coutant 0:146cf26a9bbb 619 rcc_ex_clk_init_struct.PLL2.PLL2N = 429;
Jerome Coutant 0:146cf26a9bbb 620 rcc_ex_clk_init_struct.PLL2.PLL2M = 25;
Jerome Coutant 0:146cf26a9bbb 621 HAL_RCCEx_PeriphCLKConfig(&rcc_ex_clk_init_struct);
Jerome Coutant 0:146cf26a9bbb 622 }
Jerome Coutant 0:146cf26a9bbb 623 else /* AUDIO_FREQUENCY_8K, AUDIO_FREQUENCY_16K, AUDIO_FREQUENCY_48K, AUDIO_FREQUENCY_96K */
Jerome Coutant 0:146cf26a9bbb 624 {
Jerome Coutant 0:146cf26a9bbb 625 /* SAI clock config:
Jerome Coutant 0:146cf26a9bbb 626 PLL2_VCO Input = HSE_VALUE/PLL2M = 1 Mhz
Jerome Coutant 0:146cf26a9bbb 627 PLL2_VCO Output = PLL2_VCO Input * PLL2N = 344 Mhz
Jerome Coutant 0:146cf26a9bbb 628 SAI_CLK_x = PLL2_VCO Output/PLL2P = 344/7 = 49.142 Mhz */
Jerome Coutant 0:146cf26a9bbb 629 rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
Jerome Coutant 0:146cf26a9bbb 630 rcc_ex_clk_init_struct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLL2;
Jerome Coutant 0:146cf26a9bbb 631 rcc_ex_clk_init_struct.PLL2.PLL2P = 7;
Jerome Coutant 0:146cf26a9bbb 632 rcc_ex_clk_init_struct.PLL2.PLL2Q = 1;
Jerome Coutant 0:146cf26a9bbb 633 rcc_ex_clk_init_struct.PLL2.PLL2R = 1;
Jerome Coutant 0:146cf26a9bbb 634 rcc_ex_clk_init_struct.PLL2.PLL2N = 344;
Jerome Coutant 0:146cf26a9bbb 635 rcc_ex_clk_init_struct.PLL2.PLL2M = 25;
Jerome Coutant 0:146cf26a9bbb 636 HAL_RCCEx_PeriphCLKConfig(&rcc_ex_clk_init_struct);
Jerome Coutant 0:146cf26a9bbb 637 }
Jerome Coutant 0:146cf26a9bbb 638 }
Jerome Coutant 0:146cf26a9bbb 639 /**
Jerome Coutant 0:146cf26a9bbb 640 * @}
Jerome Coutant 0:146cf26a9bbb 641 */
Jerome Coutant 0:146cf26a9bbb 642
Jerome Coutant 0:146cf26a9bbb 643 /** @defgroup STM32H747I_DISCOVERY_AUDIO_OUT_Private_Functions OUT Private Functions
Jerome Coutant 0:146cf26a9bbb 644 * @{
Jerome Coutant 0:146cf26a9bbb 645 */
Jerome Coutant 0:146cf26a9bbb 646
Jerome Coutant 0:146cf26a9bbb 647 /*******************************************************************************
Jerome Coutant 0:146cf26a9bbb 648 HAL Callbacks
Jerome Coutant 0:146cf26a9bbb 649 *******************************************************************************/
Jerome Coutant 0:146cf26a9bbb 650 /**
Jerome Coutant 0:146cf26a9bbb 651 * @brief Tx Transfer completed callbacks.
Jerome Coutant 0:146cf26a9bbb 652 * @param hsai: SAI handle
Jerome Coutant 0:146cf26a9bbb 653 * @retval None
Jerome Coutant 0:146cf26a9bbb 654 */
Jerome Coutant 0:146cf26a9bbb 655 void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
Jerome Coutant 0:146cf26a9bbb 656 {
Jerome Coutant 0:146cf26a9bbb 657 /* Manage the remaining file size and new address offset: This function
Jerome Coutant 0:146cf26a9bbb 658 should be coded by user (its prototype is already declared in stm32h747i_discovery_audio.h) */
Jerome Coutant 0:146cf26a9bbb 659 BSP_AUDIO_OUT_TransferComplete_CallBack();
Jerome Coutant 0:146cf26a9bbb 660 }
Jerome Coutant 0:146cf26a9bbb 661
Jerome Coutant 0:146cf26a9bbb 662 /**
Jerome Coutant 0:146cf26a9bbb 663 * @brief Tx Half Transfer completed callbacks.
Jerome Coutant 0:146cf26a9bbb 664 * @param hsai: SAI handle
Jerome Coutant 0:146cf26a9bbb 665 * @retval None
Jerome Coutant 0:146cf26a9bbb 666 */
Jerome Coutant 0:146cf26a9bbb 667 void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
Jerome Coutant 0:146cf26a9bbb 668 {
Jerome Coutant 0:146cf26a9bbb 669 /* Manage the remaining file size and new address offset: This function
Jerome Coutant 0:146cf26a9bbb 670 should be coded by user (its prototype is already declared in stm32h747i_discovery_audio.h) */
Jerome Coutant 0:146cf26a9bbb 671 BSP_AUDIO_OUT_HalfTransfer_CallBack();
Jerome Coutant 0:146cf26a9bbb 672 }
Jerome Coutant 0:146cf26a9bbb 673
Jerome Coutant 0:146cf26a9bbb 674 /**
Jerome Coutant 0:146cf26a9bbb 675 * @brief SAI error callbacks.
Jerome Coutant 0:146cf26a9bbb 676 * @param hsai: SAI handle
Jerome Coutant 0:146cf26a9bbb 677 * @retval None
Jerome Coutant 0:146cf26a9bbb 678 */
Jerome Coutant 0:146cf26a9bbb 679 void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai)
Jerome Coutant 0:146cf26a9bbb 680 {
Jerome Coutant 0:146cf26a9bbb 681 if(hsai->Instance == AUDIO_OUT_SAIx)
Jerome Coutant 0:146cf26a9bbb 682 {
Jerome Coutant 0:146cf26a9bbb 683 BSP_AUDIO_OUT_Error_CallBack();
Jerome Coutant 0:146cf26a9bbb 684 }
Jerome Coutant 0:146cf26a9bbb 685 else
Jerome Coutant 0:146cf26a9bbb 686 {
Jerome Coutant 0:146cf26a9bbb 687 BSP_AUDIO_IN_Error_CallBack();
Jerome Coutant 0:146cf26a9bbb 688 }
Jerome Coutant 0:146cf26a9bbb 689 }
Jerome Coutant 0:146cf26a9bbb 690
Jerome Coutant 0:146cf26a9bbb 691 /*******************************************************************************
Jerome Coutant 0:146cf26a9bbb 692 Static Functions
Jerome Coutant 0:146cf26a9bbb 693 *******************************************************************************/
Jerome Coutant 0:146cf26a9bbb 694
Jerome Coutant 0:146cf26a9bbb 695 /**
Jerome Coutant 0:146cf26a9bbb 696 * @brief Initializes the Audio Codec audio interface (SAI).
Jerome Coutant 0:146cf26a9bbb 697 * @param SaiOutMode: Audio mode to be configured for the SAI peripheral.
Jerome Coutant 0:146cf26a9bbb 698 * @param SlotActive: Audio active slot to be configured for the SAI peripheral.
Jerome Coutant 0:146cf26a9bbb 699 * @param AudioFreq: Audio frequency to be configured for the SAI peripheral.
Jerome Coutant 0:146cf26a9bbb 700 * @note The default SlotActive configuration is set to CODEC_AUDIOFRAME_SLOT_0123
Jerome Coutant 0:146cf26a9bbb 701 * and user can update this configuration using
Jerome Coutant 0:146cf26a9bbb 702 * @retval None
Jerome Coutant 0:146cf26a9bbb 703 */
Jerome Coutant 0:146cf26a9bbb 704 static void SAIx_Out_Init(uint32_t SaiOutMode, uint32_t SlotActive, uint32_t AudioFreq)
Jerome Coutant 0:146cf26a9bbb 705 {
Jerome Coutant 0:146cf26a9bbb 706 /* Disable SAI peripheral to allow access to SAI internal registers */
Jerome Coutant 0:146cf26a9bbb 707 __HAL_SAI_DISABLE(&haudio_out_sai);
Jerome Coutant 0:146cf26a9bbb 708
Jerome Coutant 0:146cf26a9bbb 709 /* Configure SAI_Block_x
Jerome Coutant 0:146cf26a9bbb 710 LSBFirst: Disabled
Jerome Coutant 0:146cf26a9bbb 711 DataSize: 16 */
Jerome Coutant 0:146cf26a9bbb 712 haudio_out_sai.Init.MonoStereoMode = SAI_STEREOMODE;
Jerome Coutant 0:146cf26a9bbb 713 haudio_out_sai.Init.AudioFrequency = AudioFreq;
Jerome Coutant 0:146cf26a9bbb 714 haudio_out_sai.Init.AudioMode = SaiOutMode;
Jerome Coutant 0:146cf26a9bbb 715 haudio_out_sai.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
Jerome Coutant 0:146cf26a9bbb 716 haudio_out_sai.Init.Protocol = SAI_FREE_PROTOCOL;
Jerome Coutant 0:146cf26a9bbb 717 haudio_out_sai.Init.DataSize = SAI_DATASIZE_16;
Jerome Coutant 0:146cf26a9bbb 718 haudio_out_sai.Init.FirstBit = SAI_FIRSTBIT_MSB;
Jerome Coutant 0:146cf26a9bbb 719 haudio_out_sai.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
Jerome Coutant 0:146cf26a9bbb 720 haudio_out_sai.Init.Synchro = SAI_ASYNCHRONOUS;
Jerome Coutant 0:146cf26a9bbb 721 haudio_out_sai.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
Jerome Coutant 0:146cf26a9bbb 722 haudio_out_sai.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
Jerome Coutant 0:146cf26a9bbb 723 haudio_out_sai.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
Jerome Coutant 0:146cf26a9bbb 724 haudio_out_sai.Init.CompandingMode = SAI_NOCOMPANDING;
Jerome Coutant 0:146cf26a9bbb 725 haudio_out_sai.Init.TriState = SAI_OUTPUT_NOTRELEASED;
Jerome Coutant 0:146cf26a9bbb 726 haudio_out_sai.Init.Mckdiv = 0;
Jerome Coutant 0:146cf26a9bbb 727 haudio_out_sai.Init.MckOverSampling = SAI_MCK_OVERSAMPLING_DISABLE;
Jerome Coutant 0:146cf26a9bbb 728 haudio_out_sai.Init.PdmInit.Activation = DISABLE;
Jerome Coutant 0:146cf26a9bbb 729 haudio_out_sai.Init.PdmInit.ClockEnable = 0;
Jerome Coutant 0:146cf26a9bbb 730 haudio_out_sai.Init.PdmInit.MicPairsNbr = 0;
Jerome Coutant 0:146cf26a9bbb 731
Jerome Coutant 0:146cf26a9bbb 732 /* Configure SAI_Block_x Frame
Jerome Coutant 0:146cf26a9bbb 733 Frame Length: 64
Jerome Coutant 0:146cf26a9bbb 734 Frame active Length: 32
Jerome Coutant 0:146cf26a9bbb 735 FS Definition: Start frame + Channel Side identification
Jerome Coutant 0:146cf26a9bbb 736 FS Polarity: FS active Low
Jerome Coutant 0:146cf26a9bbb 737 FS Offset: FS asserted one bit before the first bit of slot 0 */
Jerome Coutant 0:146cf26a9bbb 738 haudio_out_sai.FrameInit.FrameLength = 128;
Jerome Coutant 0:146cf26a9bbb 739 haudio_out_sai.FrameInit.ActiveFrameLength = 64;
Jerome Coutant 0:146cf26a9bbb 740 haudio_out_sai.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
Jerome Coutant 0:146cf26a9bbb 741 haudio_out_sai.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
Jerome Coutant 0:146cf26a9bbb 742 haudio_out_sai.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
Jerome Coutant 0:146cf26a9bbb 743
Jerome Coutant 0:146cf26a9bbb 744 /* Configure SAI Block_x Slot
Jerome Coutant 0:146cf26a9bbb 745 Slot First Bit Offset: 0
Jerome Coutant 0:146cf26a9bbb 746 Slot Size : 16
Jerome Coutant 0:146cf26a9bbb 747 Slot Number: 4
Jerome Coutant 0:146cf26a9bbb 748 Slot Active: All slot actives */
Jerome Coutant 0:146cf26a9bbb 749 haudio_out_sai.SlotInit.FirstBitOffset = 0;
Jerome Coutant 0:146cf26a9bbb 750 haudio_out_sai.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
Jerome Coutant 0:146cf26a9bbb 751 haudio_out_sai.SlotInit.SlotNumber = 4;
Jerome Coutant 0:146cf26a9bbb 752 haudio_out_sai.SlotInit.SlotActive = SlotActive;
Jerome Coutant 0:146cf26a9bbb 753 HAL_SAI_Init(&haudio_out_sai);
Jerome Coutant 0:146cf26a9bbb 754
Jerome Coutant 0:146cf26a9bbb 755 /* Enable SAI peripheral to generate MCLK */
Jerome Coutant 0:146cf26a9bbb 756 __HAL_SAI_ENABLE(&haudio_out_sai);
Jerome Coutant 0:146cf26a9bbb 757 }
Jerome Coutant 0:146cf26a9bbb 758
Jerome Coutant 0:146cf26a9bbb 759 /**
Jerome Coutant 0:146cf26a9bbb 760 * @brief Deinitializes the Audio Codec audio interface (SAI).
Jerome Coutant 0:146cf26a9bbb 761 * @retval None
Jerome Coutant 0:146cf26a9bbb 762 */
Jerome Coutant 0:146cf26a9bbb 763 static void SAIx_Out_DeInit(SAI_HandleTypeDef *hsai)
Jerome Coutant 0:146cf26a9bbb 764 {
Jerome Coutant 0:146cf26a9bbb 765 /* Disable SAI peripheral */
Jerome Coutant 0:146cf26a9bbb 766 __HAL_SAI_DISABLE(hsai);
Jerome Coutant 0:146cf26a9bbb 767
Jerome Coutant 0:146cf26a9bbb 768 HAL_SAI_DeInit(hsai);
Jerome Coutant 0:146cf26a9bbb 769 }
Jerome Coutant 0:146cf26a9bbb 770
Jerome Coutant 0:146cf26a9bbb 771 /**
Jerome Coutant 0:146cf26a9bbb 772 * @}
Jerome Coutant 0:146cf26a9bbb 773 */
Jerome Coutant 0:146cf26a9bbb 774
Jerome Coutant 0:146cf26a9bbb 775 /** @defgroup STM32H747I_DISCOVERY_AUDIO_IN_Exported_Functions IN Exported Functions
Jerome Coutant 0:146cf26a9bbb 776 * @{
Jerome Coutant 0:146cf26a9bbb 777 */
Jerome Coutant 0:146cf26a9bbb 778
Jerome Coutant 0:146cf26a9bbb 779 /**
Jerome Coutant 0:146cf26a9bbb 780 * @brief Initialize wave recording.
Jerome Coutant 0:146cf26a9bbb 781 * @param AudioFreq: Audio frequency to be configured for the DFSDM peripheral.
Jerome Coutant 0:146cf26a9bbb 782 * @param BitRes: Audio frequency to be configured for the DFSDM peripheral.
Jerome Coutant 0:146cf26a9bbb 783 * @param ChnlNbr: Audio frequency to be configured for the DFSDM peripheral.
Jerome Coutant 0:146cf26a9bbb 784 * @retval AUDIO_OK if correct communication, else wrong communication
Jerome Coutant 0:146cf26a9bbb 785 */
Jerome Coutant 0:146cf26a9bbb 786 uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
Jerome Coutant 0:146cf26a9bbb 787 {
Jerome Coutant 0:146cf26a9bbb 788 /* Set audio in interface to default one */
Jerome Coutant 0:146cf26a9bbb 789 BSP_AUDIO_IN_SelectInterface(AUDIO_IN_INTERFACE_PDM);
Jerome Coutant 0:146cf26a9bbb 790 return BSP_AUDIO_IN_InitEx(INPUT_DEVICE_DIGITAL_MIC, AudioFreq, BitRes, ChnlNbr);
Jerome Coutant 0:146cf26a9bbb 791 }
Jerome Coutant 0:146cf26a9bbb 792
Jerome Coutant 0:146cf26a9bbb 793 /**
Jerome Coutant 0:146cf26a9bbb 794 * @brief Initialize wave recording.
Jerome Coutant 0:146cf26a9bbb 795 * @param InputDevice: INPUT_DEVICE_DIGITAL_MIC or INPUT_DEVICE_ANALOG_MIC.
Jerome Coutant 0:146cf26a9bbb 796 * @param AudioFreq: Audio frequency to be configured.
Jerome Coutant 0:146cf26a9bbb 797 * @param BitRes: Audio bit resolution to be configured..
Jerome Coutant 0:146cf26a9bbb 798 * @param ChnlNbr: Number of channel to be configured.
Jerome Coutant 0:146cf26a9bbb 799 * @retval AUDIO_OK if correct communication, else wrong communication
Jerome Coutant 0:146cf26a9bbb 800 */
Jerome Coutant 0:146cf26a9bbb 801 uint8_t BSP_AUDIO_IN_InitEx(uint16_t InputDevice, uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
Jerome Coutant 0:146cf26a9bbb 802 {
Jerome Coutant 0:146cf26a9bbb 803 uint8_t ret = AUDIO_OK;
Jerome Coutant 0:146cf26a9bbb 804 uint32_t slot_active;
Jerome Coutant 0:146cf26a9bbb 805
Jerome Coutant 0:146cf26a9bbb 806 /* Store the audio record context */
Jerome Coutant 0:146cf26a9bbb 807 hAudioIn.Frequency = AudioFreq;
Jerome Coutant 0:146cf26a9bbb 808 hAudioIn.BitResolution = BitRes;
Jerome Coutant 0:146cf26a9bbb 809 hAudioIn.InputDevice = InputDevice;
Jerome Coutant 0:146cf26a9bbb 810 hAudioIn.ChannelNbr = ChnlNbr;
Jerome Coutant 0:146cf26a9bbb 811
Jerome Coutant 0:146cf26a9bbb 812 if(hAudioIn.InputDevice == INPUT_DEVICE_DIGITAL_MIC)
Jerome Coutant 0:146cf26a9bbb 813 {
Jerome Coutant 0:146cf26a9bbb 814 if(hAudioIn.Interface == AUDIO_IN_INTERFACE_SAI)
Jerome Coutant 0:146cf26a9bbb 815 {
Jerome Coutant 0:146cf26a9bbb 816 /* Initialize SAI1 block B as SLAVE RX synchrounous with SAI1 block A */
Jerome Coutant 0:146cf26a9bbb 817 haudio_in_sai.Instance = AUDIO_IN_SAIx;
Jerome Coutant 0:146cf26a9bbb 818
Jerome Coutant 0:146cf26a9bbb 819 /* Disable SAI */
Jerome Coutant 0:146cf26a9bbb 820 SAIx_In_DeInit(&haudio_in_sai);
Jerome Coutant 0:146cf26a9bbb 821
Jerome Coutant 0:146cf26a9bbb 822 /* PLL clock is set depending on the AudioFreq (44.1khz vs 48khz groups) */
Jerome Coutant 0:146cf26a9bbb 823 BSP_AUDIO_IN_ClockConfig(AudioFreq, NULL); /* Clock config is shared between AUDIO IN and OUT */
Jerome Coutant 0:146cf26a9bbb 824
Jerome Coutant 0:146cf26a9bbb 825 /* SAI data transfer preparation:
Jerome Coutant 0:146cf26a9bbb 826 Prepare the Media to be used for the audio transfer from SAI peripheral to memory */
Jerome Coutant 0:146cf26a9bbb 827 if(HAL_SAI_GetState(&haudio_in_sai) == HAL_SAI_STATE_RESET)
Jerome Coutant 0:146cf26a9bbb 828 {
Jerome Coutant 0:146cf26a9bbb 829 /* Init the SAI MSP: this __weak function can be redefined by the application*/
Jerome Coutant 0:146cf26a9bbb 830 BSP_AUDIO_IN_MspInit();
Jerome Coutant 0:146cf26a9bbb 831 }
Jerome Coutant 0:146cf26a9bbb 832
Jerome Coutant 0:146cf26a9bbb 833 /* Configure SAI in master mode :
Jerome Coutant 0:146cf26a9bbb 834 * - SAI1_block_B in slave RX mode synchronous from SAI1_block_A
Jerome Coutant 0:146cf26a9bbb 835 */
Jerome Coutant 0:146cf26a9bbb 836 slot_active = CODEC_AUDIOFRAME_SLOT_13;
Jerome Coutant 0:146cf26a9bbb 837 SAIx_In_Init(SAI_MODESLAVE_RX, slot_active, AudioFreq);
Jerome Coutant 0:146cf26a9bbb 838 }
Jerome Coutant 0:146cf26a9bbb 839 else if(hAudioIn.Interface == AUDIO_IN_INTERFACE_PDM)
Jerome Coutant 0:146cf26a9bbb 840 {
Jerome Coutant 0:146cf26a9bbb 841 /* Initialize SAI1 block A as MASTER RX */
Jerome Coutant 0:146cf26a9bbb 842 haudio_in_sai.Instance = AUDIO_IN_SAI_PDMx;
Jerome Coutant 0:146cf26a9bbb 843
Jerome Coutant 0:146cf26a9bbb 844 /* Disable SAI */
Jerome Coutant 0:146cf26a9bbb 845 SAIx_In_DeInit(&haudio_in_sai);
Jerome Coutant 0:146cf26a9bbb 846
Jerome Coutant 0:146cf26a9bbb 847 /* PLL clock is set depending on the AudioFreq (44.1khz vs 48khz groups) */
Jerome Coutant 0:146cf26a9bbb 848 BSP_AUDIO_IN_ClockConfig(AudioFreq, NULL);
Jerome Coutant 0:146cf26a9bbb 849
Jerome Coutant 0:146cf26a9bbb 850 /* SAI data transfer preparation:
Jerome Coutant 0:146cf26a9bbb 851 Prepare the Media to be used for the audio transfer from SAI peripheral to memory */
Jerome Coutant 0:146cf26a9bbb 852 /* Initialize the haudio_in_sai Instance parameter */
Jerome Coutant 0:146cf26a9bbb 853
Jerome Coutant 0:146cf26a9bbb 854 if(HAL_SAI_GetState(&haudio_in_sai) == HAL_SAI_STATE_RESET)
Jerome Coutant 0:146cf26a9bbb 855 {
Jerome Coutant 0:146cf26a9bbb 856 /* Init the SAI MSP: this __weak function can be redefined by the application*/
Jerome Coutant 0:146cf26a9bbb 857 BSP_AUDIO_IN_MspInit();
Jerome Coutant 0:146cf26a9bbb 858 }
Jerome Coutant 0:146cf26a9bbb 859
Jerome Coutant 0:146cf26a9bbb 860 /* Configure SAI in master mode :
Jerome Coutant 0:146cf26a9bbb 861 * - SAI1_block_A in master RX mode
Jerome Coutant 0:146cf26a9bbb 862 */
Jerome Coutant 0:146cf26a9bbb 863 slot_active = CODEC_AUDIOFRAME_SLOT_0;
Jerome Coutant 0:146cf26a9bbb 864 SAIx_In_Init(SAI_MODEMASTER_RX, slot_active, AudioFreq);
Jerome Coutant 0:146cf26a9bbb 865
Jerome Coutant 0:146cf26a9bbb 866 if(BSP_AUDIO_IN_PDMToPCM_Init(AudioFreq, hAudioIn.ChannelNbr, hAudioIn.ChannelNbr) != AUDIO_OK)
Jerome Coutant 0:146cf26a9bbb 867 {
Jerome Coutant 0:146cf26a9bbb 868 ret = AUDIO_ERROR;
Jerome Coutant 0:146cf26a9bbb 869 }
Jerome Coutant 0:146cf26a9bbb 870 }
Jerome Coutant 0:146cf26a9bbb 871 else
Jerome Coutant 0:146cf26a9bbb 872 {
Jerome Coutant 0:146cf26a9bbb 873 ret = AUDIO_ERROR;
Jerome Coutant 0:146cf26a9bbb 874 }
Jerome Coutant 0:146cf26a9bbb 875 }
Jerome Coutant 0:146cf26a9bbb 876 else
Jerome Coutant 0:146cf26a9bbb 877 {
Jerome Coutant 0:146cf26a9bbb 878 /* Analog Input */
Jerome Coutant 0:146cf26a9bbb 879 ret = AUDIO_ERROR;
Jerome Coutant 0:146cf26a9bbb 880 }
Jerome Coutant 0:146cf26a9bbb 881
Jerome Coutant 0:146cf26a9bbb 882 /* Return AUDIO_OK when all operations are correctly done */
Jerome Coutant 0:146cf26a9bbb 883 return ret;
Jerome Coutant 0:146cf26a9bbb 884 }
Jerome Coutant 0:146cf26a9bbb 885
Jerome Coutant 0:146cf26a9bbb 886
Jerome Coutant 0:146cf26a9bbb 887 /**
Jerome Coutant 0:146cf26a9bbb 888 * @brief Initializes wave recording and playback in parallel.
Jerome Coutant 0:146cf26a9bbb 889 * @param InputDevice: INPUT_DEVICE_DIGITAL_MICROPHONE_2
Jerome Coutant 0:146cf26a9bbb 890 * @param OutputDevice: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
Jerome Coutant 0:146cf26a9bbb 891 * or OUTPUT_DEVICE_BOTH.
Jerome Coutant 0:146cf26a9bbb 892 * @param AudioFreq: Audio frequency to be configured for the SAI peripheral.
Jerome Coutant 0:146cf26a9bbb 893 * @param BitRes: Audio frequency to be configured.
Jerome Coutant 0:146cf26a9bbb 894 * @param ChnlNbr: Channel number.
Jerome Coutant 0:146cf26a9bbb 895 * @retval AUDIO_OK if correct communication, else wrong communication
Jerome Coutant 0:146cf26a9bbb 896 */
Jerome Coutant 0:146cf26a9bbb 897 uint8_t BSP_AUDIO_IN_OUT_Init(uint32_t InputDevice, uint32_t OutputDevice, uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
Jerome Coutant 0:146cf26a9bbb 898 {
Jerome Coutant 0:146cf26a9bbb 899 uint32_t slot_active;
Jerome Coutant 0:146cf26a9bbb 900 uint32_t deviceid = 0, ret = AUDIO_OK;
Jerome Coutant 0:146cf26a9bbb 901
Jerome Coutant 0:146cf26a9bbb 902 /* Store the audio record context */
Jerome Coutant 0:146cf26a9bbb 903 hAudioIn.Frequency = AudioFreq;
Jerome Coutant 0:146cf26a9bbb 904 hAudioIn.BitResolution = BitRes;
Jerome Coutant 0:146cf26a9bbb 905 hAudioIn.InputDevice = InputDevice;
Jerome Coutant 0:146cf26a9bbb 906 hAudioIn.ChannelNbr = ChnlNbr;
Jerome Coutant 0:146cf26a9bbb 907
Jerome Coutant 0:146cf26a9bbb 908 /* Input device is Digital MIC2 and Codec interface is SAI */
Jerome Coutant 0:146cf26a9bbb 909 if (hAudioIn.InputDevice == INPUT_DEVICE_DIGITAL_MICROPHONE_2)
Jerome Coutant 0:146cf26a9bbb 910 {
Jerome Coutant 0:146cf26a9bbb 911 haudio_in_sai.Instance = AUDIO_IN_SAIx;
Jerome Coutant 0:146cf26a9bbb 912 haudio_out_sai.Instance = AUDIO_OUT_SAIx;
Jerome Coutant 0:146cf26a9bbb 913
Jerome Coutant 0:146cf26a9bbb 914 /* PLL clock is set depending on the AudioFreq (44.1khz vs 48khz groups) */
Jerome Coutant 0:146cf26a9bbb 915 BSP_AUDIO_OUT_ClockConfig(&haudio_in_sai, AudioFreq, NULL);
Jerome Coutant 0:146cf26a9bbb 916 /* SAI data transfer preparation:
Jerome Coutant 0:146cf26a9bbb 917 Prepare the Media to be used for the audio transfer from SAI peripheral to memory */
Jerome Coutant 0:146cf26a9bbb 918 if(HAL_SAI_GetState(&haudio_in_sai) == HAL_SAI_STATE_RESET)
Jerome Coutant 0:146cf26a9bbb 919 {
Jerome Coutant 0:146cf26a9bbb 920 /* Init the SAI MSP: this __weak function can be redefined by the application*/
Jerome Coutant 0:146cf26a9bbb 921 BSP_AUDIO_IN_MspInit();
Jerome Coutant 0:146cf26a9bbb 922 }
Jerome Coutant 0:146cf26a9bbb 923
Jerome Coutant 0:146cf26a9bbb 924 /* SAI data transfer preparation:
Jerome Coutant 0:146cf26a9bbb 925 Prepare the Media to be used for the audio transfer from memory to SAI peripheral */
Jerome Coutant 0:146cf26a9bbb 926 if(HAL_SAI_GetState(&haudio_out_sai) == HAL_SAI_STATE_RESET)
Jerome Coutant 0:146cf26a9bbb 927 {
Jerome Coutant 0:146cf26a9bbb 928 /* Init the SAI MSP: this __weak function can be redefined by the application*/
Jerome Coutant 0:146cf26a9bbb 929 BSP_AUDIO_OUT_MspInit(&haudio_out_sai, NULL);
Jerome Coutant 0:146cf26a9bbb 930 }
Jerome Coutant 0:146cf26a9bbb 931
Jerome Coutant 0:146cf26a9bbb 932 /* Configure SAI in master TX mode :
Jerome Coutant 0:146cf26a9bbb 933 * - SAI1_block_A in master TX mode
Jerome Coutant 0:146cf26a9bbb 934 * - SAI1_block_B in slave RX mode synchronous from SAI1_block_A
Jerome Coutant 0:146cf26a9bbb 935 */
Jerome Coutant 0:146cf26a9bbb 936 slot_active = CODEC_AUDIOFRAME_SLOT_13;
Jerome Coutant 0:146cf26a9bbb 937 SAIx_In_Init(SAI_MODESLAVE_RX, slot_active, AudioFreq);
Jerome Coutant 0:146cf26a9bbb 938
Jerome Coutant 0:146cf26a9bbb 939 slot_active = CODEC_AUDIOFRAME_SLOT_02;
Jerome Coutant 0:146cf26a9bbb 940 SAIx_Out_Init(SAI_MODEMASTER_TX, slot_active, AudioFreq);
Jerome Coutant 0:146cf26a9bbb 941
Jerome Coutant 0:146cf26a9bbb 942 /* wm8994 codec initialization */
Jerome Coutant 0:146cf26a9bbb 943 deviceid = wm8994_drv.ReadID(AUDIO_I2C_ADDRESS);
Jerome Coutant 0:146cf26a9bbb 944
Jerome Coutant 0:146cf26a9bbb 945 if((deviceid) == WM8994_ID)
Jerome Coutant 0:146cf26a9bbb 946 {
Jerome Coutant 0:146cf26a9bbb 947 /* Reset the Codec Registers */
Jerome Coutant 0:146cf26a9bbb 948 wm8994_drv.Reset(AUDIO_I2C_ADDRESS);
Jerome Coutant 0:146cf26a9bbb 949 /* Initialize the audio driver structure */
Jerome Coutant 0:146cf26a9bbb 950 audio_drv = &wm8994_drv;
Jerome Coutant 0:146cf26a9bbb 951 ret = AUDIO_OK;
Jerome Coutant 0:146cf26a9bbb 952 }
Jerome Coutant 0:146cf26a9bbb 953 else
Jerome Coutant 0:146cf26a9bbb 954 {
Jerome Coutant 0:146cf26a9bbb 955 ret = AUDIO_ERROR;
Jerome Coutant 0:146cf26a9bbb 956 }
Jerome Coutant 0:146cf26a9bbb 957
Jerome Coutant 0:146cf26a9bbb 958 if(ret == AUDIO_OK)
Jerome Coutant 0:146cf26a9bbb 959 {
Jerome Coutant 0:146cf26a9bbb 960 /* Initialize the codec internal registers */
Jerome Coutant 0:146cf26a9bbb 961 audio_drv->Init(AUDIO_I2C_ADDRESS, InputDevice|OutputDevice, 90, AudioFreq);
Jerome Coutant 0:146cf26a9bbb 962 }
Jerome Coutant 0:146cf26a9bbb 963 }
Jerome Coutant 0:146cf26a9bbb 964 else
Jerome Coutant 0:146cf26a9bbb 965 {
Jerome Coutant 0:146cf26a9bbb 966 ret = AUDIO_ERROR;
Jerome Coutant 0:146cf26a9bbb 967 }
Jerome Coutant 0:146cf26a9bbb 968
Jerome Coutant 0:146cf26a9bbb 969 /* Return AUDIO_OK when all operations are correctly done */
Jerome Coutant 0:146cf26a9bbb 970 return ret;
Jerome Coutant 0:146cf26a9bbb 971 }
Jerome Coutant 0:146cf26a9bbb 972
Jerome Coutant 0:146cf26a9bbb 973 /**
Jerome Coutant 0:146cf26a9bbb 974 * @brief Link digital mic to specified source
Jerome Coutant 0:146cf26a9bbb 975 * @param Interface : Audio In interface for Digital mic. It can be:
Jerome Coutant 0:146cf26a9bbb 976 * AUDIO_IN_INTERFACE_SAI
Jerome Coutant 0:146cf26a9bbb 977 * AUDIO_IN_INTERFACE_PDM
Jerome Coutant 0:146cf26a9bbb 978 * @retval None
Jerome Coutant 0:146cf26a9bbb 979 */
Jerome Coutant 0:146cf26a9bbb 980 void BSP_AUDIO_IN_SelectInterface(uint32_t Interface)
Jerome Coutant 0:146cf26a9bbb 981 {
Jerome Coutant 0:146cf26a9bbb 982 hAudioIn.Interface = Interface;
Jerome Coutant 0:146cf26a9bbb 983 }
Jerome Coutant 0:146cf26a9bbb 984
Jerome Coutant 0:146cf26a9bbb 985 /**
Jerome Coutant 0:146cf26a9bbb 986 * @brief Get digital mic interface
Jerome Coutant 0:146cf26a9bbb 987 * @retval Digital mic interface.
Jerome Coutant 0:146cf26a9bbb 988 */
Jerome Coutant 0:146cf26a9bbb 989 uint32_t BSP_AUDIO_IN_GetInterface(void)
Jerome Coutant 0:146cf26a9bbb 990 {
Jerome Coutant 0:146cf26a9bbb 991 return (hAudioIn.Interface);
Jerome Coutant 0:146cf26a9bbb 992 }
Jerome Coutant 0:146cf26a9bbb 993
Jerome Coutant 0:146cf26a9bbb 994 /**
Jerome Coutant 0:146cf26a9bbb 995 * @brief Return audio in channel number
Jerome Coutant 0:146cf26a9bbb 996 * @retval Number of channel
Jerome Coutant 0:146cf26a9bbb 997 */
Jerome Coutant 0:146cf26a9bbb 998 uint8_t BSP_AUDIO_IN_GetChannelNumber(void)
Jerome Coutant 0:146cf26a9bbb 999 {
Jerome Coutant 0:146cf26a9bbb 1000 return hAudioIn.ChannelNbr;
Jerome Coutant 0:146cf26a9bbb 1001 }
Jerome Coutant 0:146cf26a9bbb 1002
Jerome Coutant 0:146cf26a9bbb 1003 /**
Jerome Coutant 0:146cf26a9bbb 1004 * @brief Start audio recording.
Jerome Coutant 0:146cf26a9bbb 1005 * @param pBuf: Main buffer pointer for the recorded data storing
Jerome Coutant 0:146cf26a9bbb 1006 * @param size: Current size of the recorded buffer
Jerome Coutant 0:146cf26a9bbb 1007 * @retval AUDIO_OK if correct communication, else wrong communication
Jerome Coutant 0:146cf26a9bbb 1008 */
Jerome Coutant 0:146cf26a9bbb 1009 uint8_t BSP_AUDIO_IN_Record(uint16_t *pBuf, uint32_t size)
Jerome Coutant 0:146cf26a9bbb 1010 {
Jerome Coutant 0:146cf26a9bbb 1011 /* Start the process receive DMA */
Jerome Coutant 0:146cf26a9bbb 1012 if(HAL_OK != HAL_SAI_Receive_DMA(&haudio_in_sai, (uint8_t*)pBuf, size))
Jerome Coutant 0:146cf26a9bbb 1013 {
Jerome Coutant 0:146cf26a9bbb 1014 return AUDIO_ERROR;
Jerome Coutant 0:146cf26a9bbb 1015 }
Jerome Coutant 0:146cf26a9bbb 1016
Jerome Coutant 0:146cf26a9bbb 1017 /* Return AUDIO_OK when all operations are correctly done */
Jerome Coutant 0:146cf26a9bbb 1018 return AUDIO_OK;
Jerome Coutant 0:146cf26a9bbb 1019 }
Jerome Coutant 0:146cf26a9bbb 1020
Jerome Coutant 0:146cf26a9bbb 1021 /**
Jerome Coutant 0:146cf26a9bbb 1022 * @brief Stop audio recording.
Jerome Coutant 0:146cf26a9bbb 1023 * @retval AUDIO_OK if correct communication, else wrong communication
Jerome Coutant 0:146cf26a9bbb 1024 */
Jerome Coutant 0:146cf26a9bbb 1025 uint8_t BSP_AUDIO_IN_Stop(void)
Jerome Coutant 0:146cf26a9bbb 1026 {
Jerome Coutant 0:146cf26a9bbb 1027 /* Call the Media layer stop function */
Jerome Coutant 0:146cf26a9bbb 1028 HAL_SAI_DMAStop(&haudio_in_sai);
Jerome Coutant 0:146cf26a9bbb 1029
Jerome Coutant 0:146cf26a9bbb 1030 /* Return AUDIO_OK when all operations are correctly done */
Jerome Coutant 0:146cf26a9bbb 1031 return AUDIO_OK;
Jerome Coutant 0:146cf26a9bbb 1032 }
Jerome Coutant 0:146cf26a9bbb 1033
Jerome Coutant 0:146cf26a9bbb 1034 /**
Jerome Coutant 0:146cf26a9bbb 1035 * @brief Pause the audio file stream.
Jerome Coutant 0:146cf26a9bbb 1036 * @retval AUDIO_OK if correct communication, else wrong communication
Jerome Coutant 0:146cf26a9bbb 1037 */
Jerome Coutant 0:146cf26a9bbb 1038 uint8_t BSP_AUDIO_IN_Pause(void)
Jerome Coutant 0:146cf26a9bbb 1039 {
Jerome Coutant 0:146cf26a9bbb 1040 if (hAudioIn.InputDevice == INPUT_DEVICE_ANALOG_MIC)
Jerome Coutant 0:146cf26a9bbb 1041 {
Jerome Coutant 0:146cf26a9bbb 1042 return AUDIO_ERROR;
Jerome Coutant 0:146cf26a9bbb 1043 }
Jerome Coutant 0:146cf26a9bbb 1044 else
Jerome Coutant 0:146cf26a9bbb 1045 {
Jerome Coutant 0:146cf26a9bbb 1046 /* Call the Media layer pause function */
Jerome Coutant 0:146cf26a9bbb 1047 HAL_SAI_DMAPause(&haudio_in_sai);
Jerome Coutant 0:146cf26a9bbb 1048 }
Jerome Coutant 0:146cf26a9bbb 1049
Jerome Coutant 0:146cf26a9bbb 1050 /* Return AUDIO_OK when all operations are correctly done */
Jerome Coutant 0:146cf26a9bbb 1051 return AUDIO_OK;
Jerome Coutant 0:146cf26a9bbb 1052 }
Jerome Coutant 0:146cf26a9bbb 1053
Jerome Coutant 0:146cf26a9bbb 1054 /**
Jerome Coutant 0:146cf26a9bbb 1055 * @brief Resume the audio file stream.
Jerome Coutant 0:146cf26a9bbb 1056 * @retval AUDIO_OK if correct communication, else wrong communication
Jerome Coutant 0:146cf26a9bbb 1057 */
Jerome Coutant 0:146cf26a9bbb 1058 uint8_t BSP_AUDIO_IN_Resume(void)
Jerome Coutant 0:146cf26a9bbb 1059 {
Jerome Coutant 0:146cf26a9bbb 1060 if (hAudioIn.InputDevice == INPUT_DEVICE_ANALOG_MIC)
Jerome Coutant 0:146cf26a9bbb 1061 {
Jerome Coutant 0:146cf26a9bbb 1062 return AUDIO_ERROR;
Jerome Coutant 0:146cf26a9bbb 1063 }
Jerome Coutant 0:146cf26a9bbb 1064 else
Jerome Coutant 0:146cf26a9bbb 1065 {
Jerome Coutant 0:146cf26a9bbb 1066 /* Call the Media layer resume function */
Jerome Coutant 0:146cf26a9bbb 1067 HAL_SAI_DMAResume(&haudio_in_sai);
Jerome Coutant 0:146cf26a9bbb 1068 }
Jerome Coutant 0:146cf26a9bbb 1069
Jerome Coutant 0:146cf26a9bbb 1070 /* Return AUDIO_OK when all operations are correctly done */
Jerome Coutant 0:146cf26a9bbb 1071 return AUDIO_OK;
Jerome Coutant 0:146cf26a9bbb 1072 }
Jerome Coutant 0:146cf26a9bbb 1073
Jerome Coutant 0:146cf26a9bbb 1074 /**
Jerome Coutant 0:146cf26a9bbb 1075 * @brief Controls the audio in volume level.
Jerome Coutant 0:146cf26a9bbb 1076 * @param Volume: Volume level to be set in percentage from 0% to 100% (0 for
Jerome Coutant 0:146cf26a9bbb 1077 * Mute and 100 for Max volume level).
Jerome Coutant 0:146cf26a9bbb 1078 * @retval AUDIO_OK if correct communication, else wrong communication
Jerome Coutant 0:146cf26a9bbb 1079 */
Jerome Coutant 0:146cf26a9bbb 1080 uint8_t BSP_AUDIO_IN_SetVolume(uint8_t Volume)
Jerome Coutant 0:146cf26a9bbb 1081 {
Jerome Coutant 0:146cf26a9bbb 1082 /* Set the Global variable AudioInVolume */
Jerome Coutant 0:146cf26a9bbb 1083 AudioInVolume = Volume;
Jerome Coutant 0:146cf26a9bbb 1084
Jerome Coutant 0:146cf26a9bbb 1085 /* Return AUDIO_OK when all operations are correctly done */
Jerome Coutant 0:146cf26a9bbb 1086 return AUDIO_OK;
Jerome Coutant 0:146cf26a9bbb 1087 }
Jerome Coutant 0:146cf26a9bbb 1088
Jerome Coutant 0:146cf26a9bbb 1089 /**
Jerome Coutant 0:146cf26a9bbb 1090 * @brief Deinit the audio IN peripherals.
Jerome Coutant 0:146cf26a9bbb 1091 * @retval None
Jerome Coutant 0:146cf26a9bbb 1092 */
Jerome Coutant 0:146cf26a9bbb 1093 void BSP_AUDIO_IN_DeInit(void)
Jerome Coutant 0:146cf26a9bbb 1094 {
Jerome Coutant 0:146cf26a9bbb 1095 SAIx_In_DeInit(&haudio_in_sai);
Jerome Coutant 0:146cf26a9bbb 1096
Jerome Coutant 0:146cf26a9bbb 1097 BSP_AUDIO_IN_MspDeInit();
Jerome Coutant 0:146cf26a9bbb 1098 }
Jerome Coutant 0:146cf26a9bbb 1099
Jerome Coutant 0:146cf26a9bbb 1100 /**
Jerome Coutant 0:146cf26a9bbb 1101 * @brief Initialize the PDM library.
Jerome Coutant 0:146cf26a9bbb 1102 * @param AudioFreq: Audio sampling frequency
Jerome Coutant 0:146cf26a9bbb 1103 * @param ChnlNbrIn: Number of input audio channels in the PDM buffer
Jerome Coutant 0:146cf26a9bbb 1104 * @param ChnlNbrOut: Number of desired output audio channels in the resulting PCM buffer
Jerome Coutant 0:146cf26a9bbb 1105 * @retval None
Jerome Coutant 0:146cf26a9bbb 1106 */
Jerome Coutant 0:146cf26a9bbb 1107 uint8_t BSP_AUDIO_IN_PDMToPCM_Init(uint32_t AudioFreq, uint32_t ChnlNbrIn, uint32_t ChnlNbrOut)
Jerome Coutant 0:146cf26a9bbb 1108 {
Jerome Coutant 0:146cf26a9bbb 1109 uint32_t index = 0;
Jerome Coutant 1:9716849a8de8 1110 MBED_ASSERT(0);
Jerome Coutant 0:146cf26a9bbb 1111
Jerome Coutant 0:146cf26a9bbb 1112 /* Enable CRC peripheral to unlock the PDM library */
Jerome Coutant 0:146cf26a9bbb 1113 __HAL_RCC_CRC_CLK_ENABLE();
Jerome Coutant 0:146cf26a9bbb 1114
Jerome Coutant 0:146cf26a9bbb 1115 for(index = 0; index < ChnlNbrIn; index++)
Jerome Coutant 0:146cf26a9bbb 1116 {
Jerome Coutant 0:146cf26a9bbb 1117 /* Init PDM filters */
Jerome Coutant 1:9716849a8de8 1118 // PDM_FilterHandler[index].bit_order = PDM_FILTER_BIT_ORDER_MSB;
Jerome Coutant 1:9716849a8de8 1119 // PDM_FilterHandler[index].endianness = PDM_FILTER_ENDIANNESS_LE;
Jerome Coutant 1:9716849a8de8 1120 // PDM_FilterHandler[index].high_pass_tap = 2122358088;
Jerome Coutant 1:9716849a8de8 1121 // PDM_FilterHandler[index].out_ptr_channels = ChnlNbrOut;
Jerome Coutant 1:9716849a8de8 1122 // PDM_FilterHandler[index].in_ptr_channels = ChnlNbrIn;
Jerome Coutant 1:9716849a8de8 1123 // PDM_Filter_Init((PDM_Filter_Handler_t *)(&PDM_FilterHandler[index]));
Jerome Coutant 1:9716849a8de8 1124
Jerome Coutant 0:146cf26a9bbb 1125 /* PDM lib config phase */
Jerome Coutant 1:9716849a8de8 1126 // PDM_FilterConfig[index].output_samples_number = AudioFreq/1000;
Jerome Coutant 1:9716849a8de8 1127 // PDM_FilterConfig[index].mic_gain = 24;
Jerome Coutant 1:9716849a8de8 1128 // PDM_FilterConfig[index].decimation_factor = PDM_FILTER_DEC_FACTOR_64;
Jerome Coutant 1:9716849a8de8 1129 // PDM_Filter_setConfig((PDM_Filter_Handler_t *)&PDM_FilterHandler[index], &PDM_FilterConfig[index]);
Jerome Coutant 0:146cf26a9bbb 1130 }
Jerome Coutant 0:146cf26a9bbb 1131
Jerome Coutant 0:146cf26a9bbb 1132 return AUDIO_OK;
Jerome Coutant 0:146cf26a9bbb 1133 }
Jerome Coutant 0:146cf26a9bbb 1134
Jerome Coutant 0:146cf26a9bbb 1135
Jerome Coutant 0:146cf26a9bbb 1136 /**
Jerome Coutant 0:146cf26a9bbb 1137 * @brief Converts audio format from PDM to PCM.
Jerome Coutant 0:146cf26a9bbb 1138
Jerome Coutant 0:146cf26a9bbb 1139 * @param PDMBuf: Pointer to PDM buffer data
Jerome Coutant 0:146cf26a9bbb 1140 * @param PCMBuf: Pointer to PCM buffer data
Jerome Coutant 0:146cf26a9bbb 1141 * @retval AUDIO_OK in case of success, AUDIO_ERROR otherwise
Jerome Coutant 0:146cf26a9bbb 1142 */
Jerome Coutant 0:146cf26a9bbb 1143 uint8_t BSP_AUDIO_IN_PDMToPCM(uint16_t *PDMBuf, uint16_t *PCMBuf)
Jerome Coutant 0:146cf26a9bbb 1144 {
Jerome Coutant 0:146cf26a9bbb 1145 uint32_t index = 0;
Jerome Coutant 1:9716849a8de8 1146 MBED_ASSERT(0);
Jerome Coutant 0:146cf26a9bbb 1147
Jerome Coutant 0:146cf26a9bbb 1148 for(index = 0; index < hAudioIn.ChannelNbr; index++)
Jerome Coutant 0:146cf26a9bbb 1149 {
Jerome Coutant 1:9716849a8de8 1150 // PDM_Filter(&((uint8_t*)(PDMBuf))[index], (uint16_t*)&(PCMBuf[index]), &PDM_FilterHandler[index]);
Jerome Coutant 0:146cf26a9bbb 1151 }
Jerome Coutant 0:146cf26a9bbb 1152
Jerome Coutant 0:146cf26a9bbb 1153 return AUDIO_OK;
Jerome Coutant 0:146cf26a9bbb 1154 }
Jerome Coutant 0:146cf26a9bbb 1155
Jerome Coutant 0:146cf26a9bbb 1156 /**
Jerome Coutant 0:146cf26a9bbb 1157 * @brief User callback when record buffer is filled.
Jerome Coutant 0:146cf26a9bbb 1158 * @retval None
Jerome Coutant 0:146cf26a9bbb 1159 */
Jerome Coutant 0:146cf26a9bbb 1160 __weak void BSP_AUDIO_IN_TransferComplete_CallBack(void)
Jerome Coutant 0:146cf26a9bbb 1161 {
Jerome Coutant 0:146cf26a9bbb 1162 /* This function should be implemented by the user application.
Jerome Coutant 0:146cf26a9bbb 1163 It is called into this driver when the current buffer is filled
Jerome Coutant 0:146cf26a9bbb 1164 to prepare the next buffer pointer and its size. */
Jerome Coutant 0:146cf26a9bbb 1165 }
Jerome Coutant 0:146cf26a9bbb 1166
Jerome Coutant 0:146cf26a9bbb 1167 /**
Jerome Coutant 0:146cf26a9bbb 1168 * @brief Manages the DMA Half Transfer complete event.
Jerome Coutant 0:146cf26a9bbb 1169 * @retval None
Jerome Coutant 0:146cf26a9bbb 1170 */
Jerome Coutant 0:146cf26a9bbb 1171 __weak void BSP_AUDIO_IN_HalfTransfer_CallBack(void)
Jerome Coutant 0:146cf26a9bbb 1172 {
Jerome Coutant 0:146cf26a9bbb 1173 /* This function should be implemented by the user application.
Jerome Coutant 0:146cf26a9bbb 1174 It is called into this driver when the current buffer is filled
Jerome Coutant 0:146cf26a9bbb 1175 to prepare the next buffer pointer and its size. */
Jerome Coutant 0:146cf26a9bbb 1176 }
Jerome Coutant 0:146cf26a9bbb 1177
Jerome Coutant 0:146cf26a9bbb 1178 /**
Jerome Coutant 0:146cf26a9bbb 1179 * @brief User callback when record buffer is filled.
Jerome Coutant 0:146cf26a9bbb 1180 * @param InputDevice: INPUT_DEVICE_DIGITAL_MIC1 or INPUT_DEVICE_DIGITAL_MIC2
Jerome Coutant 0:146cf26a9bbb 1181 */
Jerome Coutant 0:146cf26a9bbb 1182 __weak void BSP_AUDIO_IN_TransferComplete_CallBackEx(uint32_t InputDevice)
Jerome Coutant 0:146cf26a9bbb 1183 {
Jerome Coutant 0:146cf26a9bbb 1184 /* This function should be implemented by the user application.
Jerome Coutant 0:146cf26a9bbb 1185 It is called into this driver when the current buffer is filled
Jerome Coutant 0:146cf26a9bbb 1186 to prepare the next buffer pointer and its size. */
Jerome Coutant 0:146cf26a9bbb 1187 }
Jerome Coutant 0:146cf26a9bbb 1188
Jerome Coutant 0:146cf26a9bbb 1189 /**
Jerome Coutant 0:146cf26a9bbb 1190 * @brief User callback when record buffer is filled.
Jerome Coutant 0:146cf26a9bbb 1191 * @param InputDevice: INPUT_DEVICE_DIGITAL_MIC1 or INPUT_DEVICE_DIGITAL_MIC2
Jerome Coutant 0:146cf26a9bbb 1192 */
Jerome Coutant 0:146cf26a9bbb 1193 __weak void BSP_AUDIO_IN_HalfTransfer_CallBackEx(uint32_t InputDevice)
Jerome Coutant 0:146cf26a9bbb 1194 {
Jerome Coutant 0:146cf26a9bbb 1195 /* This function should be implemented by the user application.
Jerome Coutant 0:146cf26a9bbb 1196 It is called into this driver when the current buffer is filled
Jerome Coutant 0:146cf26a9bbb 1197 to prepare the next buffer pointer and its size. */
Jerome Coutant 0:146cf26a9bbb 1198 }
Jerome Coutant 0:146cf26a9bbb 1199
Jerome Coutant 0:146cf26a9bbb 1200 /**
Jerome Coutant 0:146cf26a9bbb 1201 * @brief Audio IN Error callback function.
Jerome Coutant 0:146cf26a9bbb 1202 * @retval None
Jerome Coutant 0:146cf26a9bbb 1203 */
Jerome Coutant 0:146cf26a9bbb 1204 __weak void BSP_AUDIO_IN_Error_CallBack(void)
Jerome Coutant 0:146cf26a9bbb 1205 {
Jerome Coutant 0:146cf26a9bbb 1206 /* This function is called when an Interrupt due to transfer error on or peripheral
Jerome Coutant 0:146cf26a9bbb 1207 error occurs. */
Jerome Coutant 0:146cf26a9bbb 1208 }
Jerome Coutant 0:146cf26a9bbb 1209
Jerome Coutant 0:146cf26a9bbb 1210 /**
Jerome Coutant 0:146cf26a9bbb 1211 * @brief Initialize BSP_AUDIO_IN MSP.
Jerome Coutant 0:146cf26a9bbb 1212 * @retval None
Jerome Coutant 0:146cf26a9bbb 1213 */
Jerome Coutant 0:146cf26a9bbb 1214 __weak void BSP_AUDIO_IN_MspInit(void)
Jerome Coutant 0:146cf26a9bbb 1215 {
Jerome Coutant 0:146cf26a9bbb 1216 SAIx_In_MspInit(&haudio_in_sai, NULL);
Jerome Coutant 0:146cf26a9bbb 1217 }
Jerome Coutant 0:146cf26a9bbb 1218
Jerome Coutant 0:146cf26a9bbb 1219 /**
Jerome Coutant 0:146cf26a9bbb 1220 * @brief DeInitialize BSP_AUDIO_IN MSP.
Jerome Coutant 0:146cf26a9bbb 1221 * @retval None
Jerome Coutant 0:146cf26a9bbb 1222 */
Jerome Coutant 0:146cf26a9bbb 1223 __weak void BSP_AUDIO_IN_MspDeInit(void)
Jerome Coutant 0:146cf26a9bbb 1224 {
Jerome Coutant 0:146cf26a9bbb 1225 SAIx_In_MspDeInit(&haudio_in_sai, NULL);
Jerome Coutant 0:146cf26a9bbb 1226 }
Jerome Coutant 0:146cf26a9bbb 1227
Jerome Coutant 0:146cf26a9bbb 1228 /**
Jerome Coutant 0:146cf26a9bbb 1229 * @brief Clock Config.
Jerome Coutant 0:146cf26a9bbb 1230 * @param AudioFreq: Audio frequency used to play the audio stream.
Jerome Coutant 0:146cf26a9bbb 1231 * @param Params: pointer on additional configuration parameters, can be NULL.
Jerome Coutant 0:146cf26a9bbb 1232 * @note This API is called by BSP_AUDIO_IN_Init()
Jerome Coutant 0:146cf26a9bbb 1233 * Being __weak it can be overwritten by the application
Jerome Coutant 0:146cf26a9bbb 1234 * @retval None
Jerome Coutant 0:146cf26a9bbb 1235 */
Jerome Coutant 0:146cf26a9bbb 1236 __weak void BSP_AUDIO_IN_ClockConfig(uint32_t AudioFreq, void *Params)
Jerome Coutant 0:146cf26a9bbb 1237 {
Jerome Coutant 0:146cf26a9bbb 1238 RCC_PeriphCLKInitTypeDef rcc_ex_clk_init_struct;
Jerome Coutant 0:146cf26a9bbb 1239
Jerome Coutant 0:146cf26a9bbb 1240 HAL_RCCEx_GetPeriphCLKConfig(&rcc_ex_clk_init_struct);
Jerome Coutant 0:146cf26a9bbb 1241
Jerome Coutant 0:146cf26a9bbb 1242 /* Set the PLL configuration according to the audio frequency */
Jerome Coutant 0:146cf26a9bbb 1243 if((AudioFreq == AUDIO_FREQUENCY_11K) || (AudioFreq == AUDIO_FREQUENCY_22K) || (AudioFreq == AUDIO_FREQUENCY_44K))
Jerome Coutant 0:146cf26a9bbb 1244 {
Jerome Coutant 0:146cf26a9bbb 1245 /* SAI clock config:
Jerome Coutant 0:146cf26a9bbb 1246 PLL2_VCO Input = HSE_VALUE/PLL2M = 1 Mhz
Jerome Coutant 0:146cf26a9bbb 1247 PLL2_VCO Output = PLL2_VCO Input * PLL2N = 429 Mhz
Jerome Coutant 0:146cf26a9bbb 1248 SAI_CLK_x = PLL2_VCO Output/PLL2P = 429/38 = 11.289 Mhz */
Jerome Coutant 0:146cf26a9bbb 1249 rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
Jerome Coutant 0:146cf26a9bbb 1250 rcc_ex_clk_init_struct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLL2;
Jerome Coutant 0:146cf26a9bbb 1251 rcc_ex_clk_init_struct.PLL2.PLL2P = 38;
Jerome Coutant 0:146cf26a9bbb 1252 rcc_ex_clk_init_struct.PLL2.PLL2Q = 1;
Jerome Coutant 0:146cf26a9bbb 1253 rcc_ex_clk_init_struct.PLL2.PLL2R = 1;
Jerome Coutant 0:146cf26a9bbb 1254 rcc_ex_clk_init_struct.PLL2.PLL2N = 429;
Jerome Coutant 0:146cf26a9bbb 1255 rcc_ex_clk_init_struct.PLL2.PLL2M = 25;
Jerome Coutant 0:146cf26a9bbb 1256 if (hAudioIn.Interface == AUDIO_IN_INTERFACE_PDM)
Jerome Coutant 0:146cf26a9bbb 1257 {
Jerome Coutant 0:146cf26a9bbb 1258 rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI4A;
Jerome Coutant 0:146cf26a9bbb 1259 rcc_ex_clk_init_struct.Sai4AClockSelection = RCC_SAI4ACLKSOURCE_PLL2;
Jerome Coutant 0:146cf26a9bbb 1260 }
Jerome Coutant 0:146cf26a9bbb 1261 HAL_RCCEx_PeriphCLKConfig(&rcc_ex_clk_init_struct);
Jerome Coutant 0:146cf26a9bbb 1262
Jerome Coutant 0:146cf26a9bbb 1263 }
Jerome Coutant 0:146cf26a9bbb 1264 else /* AUDIO_FREQUENCY_8K, AUDIO_FREQUENCY_16K, AUDIO_FREQUENCY_32K, AUDIO_FREQUENCY_48K, AUDIO_FREQUENCY_96K */
Jerome Coutant 0:146cf26a9bbb 1265 {
Jerome Coutant 0:146cf26a9bbb 1266 /* SAI clock config:
Jerome Coutant 0:146cf26a9bbb 1267 PLL2_VCO Input = HSE_VALUE/PLL2M = 1 Mhz
Jerome Coutant 0:146cf26a9bbb 1268 PLL2_VCO Output = PLL2_VCO Input * PLL2N = 344 Mhz
Jerome Coutant 0:146cf26a9bbb 1269 SAI_CLK_x = PLL2_VCO Output/PLL2P = 344/7 = 49.142 Mhz */
Jerome Coutant 0:146cf26a9bbb 1270 rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
Jerome Coutant 0:146cf26a9bbb 1271 rcc_ex_clk_init_struct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLL2;
Jerome Coutant 0:146cf26a9bbb 1272 rcc_ex_clk_init_struct.PLL2.PLL2P = 7;
Jerome Coutant 0:146cf26a9bbb 1273 rcc_ex_clk_init_struct.PLL2.PLL2Q = 1;
Jerome Coutant 0:146cf26a9bbb 1274 rcc_ex_clk_init_struct.PLL2.PLL2R = 1;
Jerome Coutant 0:146cf26a9bbb 1275 rcc_ex_clk_init_struct.PLL2.PLL2N = 344;
Jerome Coutant 0:146cf26a9bbb 1276 rcc_ex_clk_init_struct.PLL2.PLL2M = 25;
Jerome Coutant 0:146cf26a9bbb 1277 if (hAudioIn.Interface == AUDIO_IN_INTERFACE_PDM)
Jerome Coutant 0:146cf26a9bbb 1278 {
Jerome Coutant 0:146cf26a9bbb 1279 rcc_ex_clk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_SAI4A;
Jerome Coutant 0:146cf26a9bbb 1280 rcc_ex_clk_init_struct.Sai4AClockSelection = RCC_SAI4ACLKSOURCE_PLL2;
Jerome Coutant 0:146cf26a9bbb 1281 }
Jerome Coutant 0:146cf26a9bbb 1282 HAL_RCCEx_PeriphCLKConfig(&rcc_ex_clk_init_struct);
Jerome Coutant 0:146cf26a9bbb 1283 }
Jerome Coutant 0:146cf26a9bbb 1284 }
Jerome Coutant 0:146cf26a9bbb 1285 /**
Jerome Coutant 0:146cf26a9bbb 1286 * @}
Jerome Coutant 0:146cf26a9bbb 1287 */
Jerome Coutant 0:146cf26a9bbb 1288
Jerome Coutant 0:146cf26a9bbb 1289
Jerome Coutant 0:146cf26a9bbb 1290 /** @defgroup STM32H747I_DISCOVERY_AUDIO_IN_Private_Functions IN Private Functions
Jerome Coutant 0:146cf26a9bbb 1291 * @{
Jerome Coutant 0:146cf26a9bbb 1292 */
Jerome Coutant 0:146cf26a9bbb 1293
Jerome Coutant 0:146cf26a9bbb 1294 /*******************************************************************************
Jerome Coutant 0:146cf26a9bbb 1295 HAL Callbacks
Jerome Coutant 0:146cf26a9bbb 1296 *******************************************************************************/
Jerome Coutant 0:146cf26a9bbb 1297
Jerome Coutant 0:146cf26a9bbb 1298 /**
Jerome Coutant 0:146cf26a9bbb 1299 * @brief Half reception complete callback.
Jerome Coutant 0:146cf26a9bbb 1300 * @param hsai: SAI handle.
Jerome Coutant 0:146cf26a9bbb 1301 * @retval None
Jerome Coutant 0:146cf26a9bbb 1302 */
Jerome Coutant 0:146cf26a9bbb 1303 void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai)
Jerome Coutant 0:146cf26a9bbb 1304 {
Jerome Coutant 0:146cf26a9bbb 1305 /* Manage the remaining file size and new address offset: This function should be coded by user */
Jerome Coutant 0:146cf26a9bbb 1306 BSP_AUDIO_IN_HalfTransfer_CallBack();
Jerome Coutant 0:146cf26a9bbb 1307 }
Jerome Coutant 0:146cf26a9bbb 1308
Jerome Coutant 0:146cf26a9bbb 1309 /**
Jerome Coutant 0:146cf26a9bbb 1310 * @brief Reception complete callback.
Jerome Coutant 0:146cf26a9bbb 1311 * @param hsai: SAI handle.
Jerome Coutant 0:146cf26a9bbb 1312 * @retval None
Jerome Coutant 0:146cf26a9bbb 1313 */
Jerome Coutant 0:146cf26a9bbb 1314 void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai)
Jerome Coutant 0:146cf26a9bbb 1315 {
Jerome Coutant 0:146cf26a9bbb 1316 /* Call the record update function to get the next buffer to fill and its size (size is ignored) */
Jerome Coutant 0:146cf26a9bbb 1317 BSP_AUDIO_IN_TransferComplete_CallBack();
Jerome Coutant 0:146cf26a9bbb 1318 }
Jerome Coutant 0:146cf26a9bbb 1319
Jerome Coutant 0:146cf26a9bbb 1320 /*******************************************************************************
Jerome Coutant 0:146cf26a9bbb 1321 Static Functions
Jerome Coutant 0:146cf26a9bbb 1322 *******************************************************************************/
Jerome Coutant 0:146cf26a9bbb 1323 /**
Jerome Coutant 0:146cf26a9bbb 1324 * @brief Initializes SAI Audio IN MSP.
Jerome Coutant 0:146cf26a9bbb 1325 * @param hsai: SAI handle
Jerome Coutant 0:146cf26a9bbb 1326 * @param Params: pointer on additional configuration parameters, can be NULL.
Jerome Coutant 0:146cf26a9bbb 1327 * @retval None
Jerome Coutant 0:146cf26a9bbb 1328 */
Jerome Coutant 0:146cf26a9bbb 1329 static void SAIx_In_MspInit(SAI_HandleTypeDef *hsai, void *Params)
Jerome Coutant 0:146cf26a9bbb 1330 {
Jerome Coutant 0:146cf26a9bbb 1331 static DMA_HandleTypeDef hdma_sai_rx;
Jerome Coutant 0:146cf26a9bbb 1332 GPIO_InitTypeDef gpio_init_structure;
Jerome Coutant 0:146cf26a9bbb 1333
Jerome Coutant 0:146cf26a9bbb 1334 if(hsai->Instance == AUDIO_IN_SAI_PDMx)
Jerome Coutant 0:146cf26a9bbb 1335 {
Jerome Coutant 0:146cf26a9bbb 1336 /* Enable SAI clock */
Jerome Coutant 0:146cf26a9bbb 1337 AUDIO_IN_SAI_PDMx_CLK_ENABLE();
Jerome Coutant 0:146cf26a9bbb 1338
Jerome Coutant 0:146cf26a9bbb 1339 AUDIO_IN_SAI_PDMx_CLK_IN_ENABLE();
Jerome Coutant 0:146cf26a9bbb 1340 AUDIO_IN_SAI_PDMx_DATA_IN_ENABLE();
Jerome Coutant 0:146cf26a9bbb 1341
Jerome Coutant 0:146cf26a9bbb 1342 gpio_init_structure.Pin = AUDIO_IN_SAI_PDMx_CLK_IN_PIN;
Jerome Coutant 0:146cf26a9bbb 1343 gpio_init_structure.Mode = GPIO_MODE_AF_PP;
Jerome Coutant 0:146cf26a9bbb 1344 gpio_init_structure.Pull = GPIO_NOPULL;
Jerome Coutant 0:146cf26a9bbb 1345 gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH;
Jerome Coutant 0:146cf26a9bbb 1346 gpio_init_structure.Alternate = AUDIO_IN_SAI_PDMx_DATA_CLK_AF;
Jerome Coutant 0:146cf26a9bbb 1347 HAL_GPIO_Init(AUDIO_IN_SAI_PDMx_CLK_IN_PORT, &gpio_init_structure);
Jerome Coutant 0:146cf26a9bbb 1348
Jerome Coutant 0:146cf26a9bbb 1349 gpio_init_structure.Pull = GPIO_PULLUP;
Jerome Coutant 0:146cf26a9bbb 1350 gpio_init_structure.Speed = GPIO_SPEED_FREQ_MEDIUM;
Jerome Coutant 0:146cf26a9bbb 1351 gpio_init_structure.Pin = AUDIO_IN_SAI_PDMx_DATA_IN_PIN;
Jerome Coutant 0:146cf26a9bbb 1352 HAL_GPIO_Init(AUDIO_IN_SAI_PDMx_DATA_IN_PORT, &gpio_init_structure);
Jerome Coutant 0:146cf26a9bbb 1353
Jerome Coutant 0:146cf26a9bbb 1354 AUDIO_IN_SAI_PDMx_FS_SCK_ENABLE();
Jerome Coutant 0:146cf26a9bbb 1355
Jerome Coutant 0:146cf26a9bbb 1356 /* CODEC_SAI pins configuration: FS, SCK, MCK and SD pins ------------------*/
Jerome Coutant 0:146cf26a9bbb 1357 gpio_init_structure.Pin = AUDIO_IN_SAI_PDMx_FS_PIN | AUDIO_IN_SAI_PDMx_SCK_PIN;
Jerome Coutant 0:146cf26a9bbb 1358 gpio_init_structure.Mode = GPIO_MODE_AF_PP;
Jerome Coutant 0:146cf26a9bbb 1359 gpio_init_structure.Pull = GPIO_NOPULL;
Jerome Coutant 0:146cf26a9bbb 1360 gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH;
Jerome Coutant 0:146cf26a9bbb 1361 gpio_init_structure.Alternate = AUDIO_IN_SAI_PDMx_FS_SCK_AF;
Jerome Coutant 0:146cf26a9bbb 1362 HAL_GPIO_Init(AUDIO_IN_SAI_PDMx_FS_SCK_GPIO_PORT, &gpio_init_structure);
Jerome Coutant 0:146cf26a9bbb 1363
Jerome Coutant 0:146cf26a9bbb 1364 /* Enable the DMA clock */
Jerome Coutant 0:146cf26a9bbb 1365 AUDIO_IN_SAI_PDMx_DMAx_CLK_ENABLE();
Jerome Coutant 0:146cf26a9bbb 1366
Jerome Coutant 0:146cf26a9bbb 1367 /* Configure the hdma_sai_rx handle parameters */
Jerome Coutant 0:146cf26a9bbb 1368 hdma_sai_rx.Init.Request = AUDIO_IN_SAI_PDMx_DMAx_REQUEST;
Jerome Coutant 0:146cf26a9bbb 1369 hdma_sai_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
Jerome Coutant 0:146cf26a9bbb 1370 hdma_sai_rx.Init.PeriphInc = DMA_PINC_DISABLE;
Jerome Coutant 0:146cf26a9bbb 1371 hdma_sai_rx.Init.MemInc = DMA_MINC_ENABLE;
Jerome Coutant 0:146cf26a9bbb 1372 hdma_sai_rx.Init.PeriphDataAlignment = AUDIO_IN_SAI_PDMx_DMAx_PERIPH_DATA_SIZE;
Jerome Coutant 0:146cf26a9bbb 1373 hdma_sai_rx.Init.MemDataAlignment = AUDIO_IN_SAI_PDMx_DMAx_MEM_DATA_SIZE;
Jerome Coutant 0:146cf26a9bbb 1374 hdma_sai_rx.Init.Mode = DMA_CIRCULAR;
Jerome Coutant 0:146cf26a9bbb 1375 hdma_sai_rx.Init.Priority = DMA_PRIORITY_HIGH;
Jerome Coutant 0:146cf26a9bbb 1376 hdma_sai_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
Jerome Coutant 0:146cf26a9bbb 1377 hdma_sai_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
Jerome Coutant 0:146cf26a9bbb 1378 hdma_sai_rx.Init.MemBurst = DMA_MBURST_SINGLE;
Jerome Coutant 0:146cf26a9bbb 1379 hdma_sai_rx.Init.PeriphBurst = DMA_MBURST_SINGLE;
Jerome Coutant 0:146cf26a9bbb 1380
Jerome Coutant 0:146cf26a9bbb 1381 hdma_sai_rx.Instance = AUDIO_IN_SAI_PDMx_DMAx_STREAM;
Jerome Coutant 0:146cf26a9bbb 1382
Jerome Coutant 0:146cf26a9bbb 1383 /* Associate the DMA handle */
Jerome Coutant 0:146cf26a9bbb 1384 __HAL_LINKDMA(hsai, hdmarx, hdma_sai_rx);
Jerome Coutant 0:146cf26a9bbb 1385
Jerome Coutant 0:146cf26a9bbb 1386 /* Deinitialize the Stream for new transfer */
Jerome Coutant 0:146cf26a9bbb 1387 HAL_DMA_DeInit(&hdma_sai_rx);
Jerome Coutant 0:146cf26a9bbb 1388
Jerome Coutant 0:146cf26a9bbb 1389 /* Configure the DMA Stream */
Jerome Coutant 0:146cf26a9bbb 1390 HAL_DMA_Init(&hdma_sai_rx);
Jerome Coutant 0:146cf26a9bbb 1391
Jerome Coutant 0:146cf26a9bbb 1392 /* SAI DMA IRQ Channel configuration */
Jerome Coutant 0:146cf26a9bbb 1393 HAL_NVIC_SetPriority(AUDIO_IN_SAI_PDMx_DMAx_IRQ, AUDIO_IN_IRQ_PREPRIO, 0);
Jerome Coutant 0:146cf26a9bbb 1394 HAL_NVIC_EnableIRQ(AUDIO_IN_SAI_PDMx_DMAx_IRQ);
Jerome Coutant 0:146cf26a9bbb 1395 }
Jerome Coutant 0:146cf26a9bbb 1396 else
Jerome Coutant 0:146cf26a9bbb 1397 {
Jerome Coutant 0:146cf26a9bbb 1398 /* Enable SAI clock */
Jerome Coutant 0:146cf26a9bbb 1399 AUDIO_IN_SAIx_CLK_ENABLE();
Jerome Coutant 0:146cf26a9bbb 1400
Jerome Coutant 0:146cf26a9bbb 1401 /* Enable SD GPIO clock */
Jerome Coutant 0:146cf26a9bbb 1402 AUDIO_IN_SAIx_SD_ENABLE();
Jerome Coutant 0:146cf26a9bbb 1403 /* CODEC_SAI pin configuration: SD pin */
Jerome Coutant 0:146cf26a9bbb 1404 gpio_init_structure.Pin = AUDIO_IN_SAIx_SD_PIN;
Jerome Coutant 0:146cf26a9bbb 1405 gpio_init_structure.Mode = GPIO_MODE_AF_PP;
Jerome Coutant 0:146cf26a9bbb 1406 gpio_init_structure.Pull = GPIO_NOPULL;
Jerome Coutant 0:146cf26a9bbb 1407 gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH;
Jerome Coutant 0:146cf26a9bbb 1408 gpio_init_structure.Alternate = AUDIO_IN_SAIx_AF;
Jerome Coutant 0:146cf26a9bbb 1409 HAL_GPIO_Init(AUDIO_IN_SAIx_SD_GPIO_PORT, &gpio_init_structure);
Jerome Coutant 0:146cf26a9bbb 1410
Jerome Coutant 0:146cf26a9bbb 1411 /* Enable Audio INT GPIO clock */
Jerome Coutant 0:146cf26a9bbb 1412 AUDIO_IN_INT_GPIO_ENABLE();
Jerome Coutant 0:146cf26a9bbb 1413 /* Audio INT pin configuration: input */
Jerome Coutant 0:146cf26a9bbb 1414 gpio_init_structure.Pin = AUDIO_IN_INT_GPIO_PIN;
Jerome Coutant 0:146cf26a9bbb 1415 gpio_init_structure.Mode = GPIO_MODE_INPUT;
Jerome Coutant 0:146cf26a9bbb 1416 gpio_init_structure.Pull = GPIO_NOPULL;
Jerome Coutant 0:146cf26a9bbb 1417 gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH;
Jerome Coutant 0:146cf26a9bbb 1418 HAL_GPIO_Init(AUDIO_IN_INT_GPIO_PORT, &gpio_init_structure);
Jerome Coutant 0:146cf26a9bbb 1419
Jerome Coutant 0:146cf26a9bbb 1420 /* Enable the DMA clock */
Jerome Coutant 0:146cf26a9bbb 1421 AUDIO_IN_SAIx_DMAx_CLK_ENABLE();
Jerome Coutant 0:146cf26a9bbb 1422
Jerome Coutant 0:146cf26a9bbb 1423 /* Configure the hdma_sai_rx handle parameters */
Jerome Coutant 0:146cf26a9bbb 1424 hdma_sai_rx.Init.Request = AUDIO_IN_SAIx_DMAx_REQUEST;
Jerome Coutant 0:146cf26a9bbb 1425 hdma_sai_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
Jerome Coutant 0:146cf26a9bbb 1426 hdma_sai_rx.Init.PeriphInc = DMA_PINC_DISABLE;
Jerome Coutant 0:146cf26a9bbb 1427 hdma_sai_rx.Init.MemInc = DMA_MINC_ENABLE;
Jerome Coutant 0:146cf26a9bbb 1428 hdma_sai_rx.Init.PeriphDataAlignment = AUDIO_IN_SAIx_DMAx_PERIPH_DATA_SIZE;
Jerome Coutant 0:146cf26a9bbb 1429 hdma_sai_rx.Init.MemDataAlignment = AUDIO_IN_SAIx_DMAx_MEM_DATA_SIZE;
Jerome Coutant 0:146cf26a9bbb 1430 hdma_sai_rx.Init.Mode = DMA_CIRCULAR;
Jerome Coutant 0:146cf26a9bbb 1431 hdma_sai_rx.Init.Priority = DMA_PRIORITY_HIGH;
Jerome Coutant 0:146cf26a9bbb 1432 hdma_sai_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
Jerome Coutant 0:146cf26a9bbb 1433 hdma_sai_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
Jerome Coutant 0:146cf26a9bbb 1434 hdma_sai_rx.Init.MemBurst = DMA_MBURST_SINGLE;
Jerome Coutant 0:146cf26a9bbb 1435 hdma_sai_rx.Init.PeriphBurst = DMA_MBURST_SINGLE;
Jerome Coutant 0:146cf26a9bbb 1436
Jerome Coutant 0:146cf26a9bbb 1437 hdma_sai_rx.Instance = AUDIO_IN_SAIx_DMAx_STREAM;
Jerome Coutant 0:146cf26a9bbb 1438
Jerome Coutant 0:146cf26a9bbb 1439 /* Associate the DMA handle */
Jerome Coutant 0:146cf26a9bbb 1440 __HAL_LINKDMA(hsai, hdmarx, hdma_sai_rx);
Jerome Coutant 0:146cf26a9bbb 1441
Jerome Coutant 0:146cf26a9bbb 1442 /* Deinitialize the Stream for new transfer */
Jerome Coutant 0:146cf26a9bbb 1443 HAL_DMA_DeInit(&hdma_sai_rx);
Jerome Coutant 0:146cf26a9bbb 1444
Jerome Coutant 0:146cf26a9bbb 1445 /* Configure the DMA Stream */
Jerome Coutant 0:146cf26a9bbb 1446 HAL_DMA_Init(&hdma_sai_rx);
Jerome Coutant 0:146cf26a9bbb 1447
Jerome Coutant 0:146cf26a9bbb 1448 /* SAI DMA IRQ Channel configuration */
Jerome Coutant 0:146cf26a9bbb 1449 HAL_NVIC_SetPriority(AUDIO_IN_SAIx_DMAx_IRQ, AUDIO_IN_IRQ_PREPRIO, 0);
Jerome Coutant 0:146cf26a9bbb 1450 HAL_NVIC_EnableIRQ(AUDIO_IN_SAIx_DMAx_IRQ);
Jerome Coutant 0:146cf26a9bbb 1451
Jerome Coutant 0:146cf26a9bbb 1452 /* Audio INT IRQ Channel configuration */
Jerome Coutant 0:146cf26a9bbb 1453 HAL_NVIC_SetPriority(AUDIO_IN_INT_IRQ, AUDIO_IN_IRQ_PREPRIO, 0);
Jerome Coutant 0:146cf26a9bbb 1454 HAL_NVIC_EnableIRQ(AUDIO_IN_INT_IRQ);
Jerome Coutant 0:146cf26a9bbb 1455 }
Jerome Coutant 0:146cf26a9bbb 1456 }
Jerome Coutant 0:146cf26a9bbb 1457
Jerome Coutant 0:146cf26a9bbb 1458 /**
Jerome Coutant 0:146cf26a9bbb 1459 * @brief De-Initializes SAI Audio IN MSP.
Jerome Coutant 0:146cf26a9bbb 1460 * @param hsai: SAI handle
Jerome Coutant 0:146cf26a9bbb 1461 * @param Params: pointer on additional configuration parameters, can be NULL.
Jerome Coutant 0:146cf26a9bbb 1462 * @retval None
Jerome Coutant 0:146cf26a9bbb 1463 */
Jerome Coutant 0:146cf26a9bbb 1464 static void SAIx_In_MspDeInit(SAI_HandleTypeDef *hsai, void *Params)
Jerome Coutant 0:146cf26a9bbb 1465 {
Jerome Coutant 0:146cf26a9bbb 1466 GPIO_InitTypeDef gpio_init_structure;
Jerome Coutant 0:146cf26a9bbb 1467
Jerome Coutant 0:146cf26a9bbb 1468 if(hsai->Instance == AUDIO_IN_SAI_PDMx)
Jerome Coutant 0:146cf26a9bbb 1469 {
Jerome Coutant 0:146cf26a9bbb 1470 /* Deinitialize the DMA stream */
Jerome Coutant 0:146cf26a9bbb 1471 HAL_DMA_Abort(hsai->hdmarx);
Jerome Coutant 0:146cf26a9bbb 1472
Jerome Coutant 0:146cf26a9bbb 1473 HAL_SAI_DeInit(hsai);
Jerome Coutant 0:146cf26a9bbb 1474 /* Disable SAI peripheral */
Jerome Coutant 0:146cf26a9bbb 1475 __HAL_SAI_DISABLE(hsai);
Jerome Coutant 0:146cf26a9bbb 1476
Jerome Coutant 0:146cf26a9bbb 1477 /* Deinitialize the DMA stream */
Jerome Coutant 0:146cf26a9bbb 1478 HAL_DMA_DeInit(hsai->hdmarx);
Jerome Coutant 0:146cf26a9bbb 1479
Jerome Coutant 0:146cf26a9bbb 1480 gpio_init_structure.Pin = AUDIO_IN_SAI_PDMx_CLK_IN_PIN;
Jerome Coutant 0:146cf26a9bbb 1481 HAL_GPIO_DeInit(AUDIO_IN_SAI_PDMx_CLK_IN_PORT, gpio_init_structure.Pin);
Jerome Coutant 0:146cf26a9bbb 1482
Jerome Coutant 0:146cf26a9bbb 1483 gpio_init_structure.Pin = AUDIO_IN_SAI_PDMx_DATA_IN_PIN;
Jerome Coutant 0:146cf26a9bbb 1484 HAL_GPIO_DeInit(AUDIO_IN_SAI_PDMx_DATA_IN_PORT, gpio_init_structure.Pin);
Jerome Coutant 0:146cf26a9bbb 1485
Jerome Coutant 0:146cf26a9bbb 1486 /* CODEC_SAI pins configuration: FS, SCK, MCK and SD pins ------------------*/
Jerome Coutant 0:146cf26a9bbb 1487 gpio_init_structure.Pin = AUDIO_IN_SAI_PDMx_FS_PIN | AUDIO_IN_SAI_PDMx_SCK_PIN;
Jerome Coutant 0:146cf26a9bbb 1488 HAL_GPIO_DeInit(AUDIO_IN_SAI_PDMx_FS_SCK_GPIO_PORT, gpio_init_structure.Pin);
Jerome Coutant 0:146cf26a9bbb 1489
Jerome Coutant 0:146cf26a9bbb 1490 /* Disable SAI clock */
Jerome Coutant 0:146cf26a9bbb 1491 AUDIO_IN_SAI_PDMx_CLK_DISABLE();
Jerome Coutant 0:146cf26a9bbb 1492 }
Jerome Coutant 0:146cf26a9bbb 1493 else
Jerome Coutant 0:146cf26a9bbb 1494 {
Jerome Coutant 0:146cf26a9bbb 1495 /* SAI DMA IRQ Channel deactivation */
Jerome Coutant 0:146cf26a9bbb 1496 HAL_NVIC_DisableIRQ(AUDIO_IN_SAIx_DMAx_IRQ);
Jerome Coutant 0:146cf26a9bbb 1497
Jerome Coutant 0:146cf26a9bbb 1498 if(hsai->Instance == AUDIO_IN_SAIx)
Jerome Coutant 0:146cf26a9bbb 1499 {
Jerome Coutant 0:146cf26a9bbb 1500 /* Deinitialize the DMA stream */
Jerome Coutant 0:146cf26a9bbb 1501 HAL_DMA_DeInit(hsai->hdmatx);
Jerome Coutant 0:146cf26a9bbb 1502 }
Jerome Coutant 0:146cf26a9bbb 1503
Jerome Coutant 0:146cf26a9bbb 1504 /* Disable SAI peripheral */
Jerome Coutant 0:146cf26a9bbb 1505 __HAL_SAI_DISABLE(hsai);
Jerome Coutant 0:146cf26a9bbb 1506
Jerome Coutant 0:146cf26a9bbb 1507 /* Deactivates CODEC_SAI pin SD by putting them in input mode */
Jerome Coutant 0:146cf26a9bbb 1508 gpio_init_structure.Pin = AUDIO_IN_SAIx_SD_PIN;
Jerome Coutant 0:146cf26a9bbb 1509 HAL_GPIO_DeInit(AUDIO_IN_SAIx_SD_GPIO_PORT, gpio_init_structure.Pin);
Jerome Coutant 0:146cf26a9bbb 1510
Jerome Coutant 0:146cf26a9bbb 1511 gpio_init_structure.Pin = AUDIO_IN_INT_GPIO_PIN;
Jerome Coutant 0:146cf26a9bbb 1512 HAL_GPIO_DeInit(AUDIO_IN_INT_GPIO_PORT, gpio_init_structure.Pin);
Jerome Coutant 0:146cf26a9bbb 1513
Jerome Coutant 0:146cf26a9bbb 1514 /* Disable SAI clock */
Jerome Coutant 0:146cf26a9bbb 1515 AUDIO_IN_SAIx_CLK_DISABLE();
Jerome Coutant 0:146cf26a9bbb 1516 }
Jerome Coutant 0:146cf26a9bbb 1517 }
Jerome Coutant 0:146cf26a9bbb 1518
Jerome Coutant 0:146cf26a9bbb 1519 /**
Jerome Coutant 0:146cf26a9bbb 1520 * @brief Initializes the Audio Codec audio interface (SAI).
Jerome Coutant 0:146cf26a9bbb 1521 * @param SaiInMode: Audio mode to be configured for the SAI peripheral.
Jerome Coutant 0:146cf26a9bbb 1522 * @param SlotActive: Audio active slot to be configured for the SAI peripheral.
Jerome Coutant 0:146cf26a9bbb 1523 * @param AudioFreq: Audio frequency to be configured for the SAI peripheral.
Jerome Coutant 0:146cf26a9bbb 1524 * @retval None
Jerome Coutant 0:146cf26a9bbb 1525 */
Jerome Coutant 0:146cf26a9bbb 1526 static void SAIx_In_Init(uint32_t SaiInMode, uint32_t SlotActive, uint32_t AudioFreq)
Jerome Coutant 0:146cf26a9bbb 1527 {
Jerome Coutant 0:146cf26a9bbb 1528 /* Disable SAI peripheral to allow access to SAI internal registers */
Jerome Coutant 0:146cf26a9bbb 1529 __HAL_SAI_DISABLE(&haudio_in_sai);
Jerome Coutant 0:146cf26a9bbb 1530
Jerome Coutant 0:146cf26a9bbb 1531 /* Configure SAI_Block_x
Jerome Coutant 0:146cf26a9bbb 1532 LSBFirst: Disabled
Jerome Coutant 0:146cf26a9bbb 1533 DataSize: 16 */
Jerome Coutant 0:146cf26a9bbb 1534 haudio_in_sai.Init.MonoStereoMode = SAI_STEREOMODE;
Jerome Coutant 0:146cf26a9bbb 1535 haudio_in_sai.Init.AudioFrequency = AudioFreq;
Jerome Coutant 0:146cf26a9bbb 1536 haudio_in_sai.Init.AudioMode = SaiInMode;
Jerome Coutant 0:146cf26a9bbb 1537 haudio_in_sai.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
Jerome Coutant 0:146cf26a9bbb 1538 haudio_in_sai.Init.Protocol = SAI_FREE_PROTOCOL;
Jerome Coutant 0:146cf26a9bbb 1539 haudio_in_sai.Init.DataSize = SAI_DATASIZE_16;
Jerome Coutant 0:146cf26a9bbb 1540 haudio_in_sai.Init.FirstBit = SAI_FIRSTBIT_MSB;
Jerome Coutant 0:146cf26a9bbb 1541 haudio_in_sai.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
Jerome Coutant 0:146cf26a9bbb 1542 haudio_in_sai.Init.Synchro = SAI_SYNCHRONOUS;
Jerome Coutant 0:146cf26a9bbb 1543 haudio_in_sai.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;
Jerome Coutant 0:146cf26a9bbb 1544 haudio_in_sai.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
Jerome Coutant 0:146cf26a9bbb 1545 haudio_in_sai.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
Jerome Coutant 0:146cf26a9bbb 1546 haudio_in_sai.Init.CompandingMode = SAI_NOCOMPANDING;
Jerome Coutant 0:146cf26a9bbb 1547 haudio_in_sai.Init.TriState = SAI_OUTPUT_RELEASED;
Jerome Coutant 0:146cf26a9bbb 1548 haudio_in_sai.Init.Mckdiv = 0;
Jerome Coutant 0:146cf26a9bbb 1549 haudio_in_sai.Init.MckOverSampling = SAI_MCK_OVERSAMPLING_DISABLE;
Jerome Coutant 0:146cf26a9bbb 1550 haudio_in_sai.Init.PdmInit.Activation = DISABLE;
Jerome Coutant 0:146cf26a9bbb 1551
Jerome Coutant 0:146cf26a9bbb 1552 /* Configure SAI_Block_x Frame
Jerome Coutant 0:146cf26a9bbb 1553 Frame Length: 64
Jerome Coutant 0:146cf26a9bbb 1554 Frame active Length: 32
Jerome Coutant 0:146cf26a9bbb 1555 FS Definition: Start frame + Channel Side identification
Jerome Coutant 0:146cf26a9bbb 1556 FS Polarity: FS active Low
Jerome Coutant 0:146cf26a9bbb 1557 FS Offset: FS asserted one bit before the first bit of slot 0 */
Jerome Coutant 0:146cf26a9bbb 1558 haudio_in_sai.FrameInit.FrameLength = 128;
Jerome Coutant 0:146cf26a9bbb 1559 haudio_in_sai.FrameInit.ActiveFrameLength = 64;
Jerome Coutant 0:146cf26a9bbb 1560 haudio_in_sai.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
Jerome Coutant 0:146cf26a9bbb 1561 haudio_in_sai.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
Jerome Coutant 0:146cf26a9bbb 1562 haudio_in_sai.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
Jerome Coutant 0:146cf26a9bbb 1563
Jerome Coutant 0:146cf26a9bbb 1564 /* Configure SAI Block_x Slot
Jerome Coutant 0:146cf26a9bbb 1565 Slot First Bit Offset: 0
Jerome Coutant 0:146cf26a9bbb 1566 Slot Size : 16
Jerome Coutant 0:146cf26a9bbb 1567 Slot Number: 4
Jerome Coutant 0:146cf26a9bbb 1568 Slot Active: All slot active */
Jerome Coutant 0:146cf26a9bbb 1569 haudio_in_sai.SlotInit.FirstBitOffset = 0;
Jerome Coutant 0:146cf26a9bbb 1570 haudio_in_sai.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
Jerome Coutant 0:146cf26a9bbb 1571 haudio_in_sai.SlotInit.SlotNumber = 4;
Jerome Coutant 0:146cf26a9bbb 1572 haudio_in_sai.SlotInit.SlotActive = SlotActive;
Jerome Coutant 0:146cf26a9bbb 1573
Jerome Coutant 0:146cf26a9bbb 1574 if(hAudioIn.Interface == AUDIO_IN_INTERFACE_PDM)
Jerome Coutant 0:146cf26a9bbb 1575 {
Jerome Coutant 0:146cf26a9bbb 1576 haudio_in_sai.Init.AudioFrequency = AudioFreq * 8;
Jerome Coutant 0:146cf26a9bbb 1577 haudio_in_sai.Init.Synchro = SAI_ASYNCHRONOUS;
Jerome Coutant 0:146cf26a9bbb 1578 haudio_in_sai.Init.NoDivider = SAI_MASTERDIVIDER_DISABLE;
Jerome Coutant 0:146cf26a9bbb 1579
Jerome Coutant 0:146cf26a9bbb 1580 haudio_in_sai.Init.PdmInit.Activation = ENABLE;
Jerome Coutant 0:146cf26a9bbb 1581 haudio_in_sai.Init.PdmInit.MicPairsNbr = 1;
Jerome Coutant 0:146cf26a9bbb 1582 haudio_in_sai.Init.PdmInit.ClockEnable = SAI_PDM_CLOCK1_ENABLE;
Jerome Coutant 0:146cf26a9bbb 1583 haudio_in_sai.Init.FirstBit = SAI_FIRSTBIT_LSB;
Jerome Coutant 0:146cf26a9bbb 1584 haudio_in_sai.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
Jerome Coutant 0:146cf26a9bbb 1585
Jerome Coutant 0:146cf26a9bbb 1586 haudio_in_sai.FrameInit.FrameLength = 16;
Jerome Coutant 0:146cf26a9bbb 1587 haudio_in_sai.FrameInit.ActiveFrameLength = 1;
Jerome Coutant 0:146cf26a9bbb 1588 haudio_in_sai.FrameInit.FSDefinition = SAI_FS_STARTFRAME;
Jerome Coutant 0:146cf26a9bbb 1589 haudio_in_sai.FrameInit.FSPolarity = SAI_FS_ACTIVE_HIGH;
Jerome Coutant 0:146cf26a9bbb 1590 haudio_in_sai.FrameInit.FSOffset = SAI_FS_FIRSTBIT;
Jerome Coutant 0:146cf26a9bbb 1591
Jerome Coutant 0:146cf26a9bbb 1592 haudio_in_sai.SlotInit.SlotNumber = 1;
Jerome Coutant 0:146cf26a9bbb 1593 haudio_in_sai.SlotInit.SlotActive = SlotActive;
Jerome Coutant 0:146cf26a9bbb 1594 }
Jerome Coutant 0:146cf26a9bbb 1595
Jerome Coutant 0:146cf26a9bbb 1596 HAL_SAI_Init(&haudio_in_sai);
Jerome Coutant 0:146cf26a9bbb 1597
Jerome Coutant 0:146cf26a9bbb 1598 /* Enable SAI peripheral */
Jerome Coutant 0:146cf26a9bbb 1599 __HAL_SAI_ENABLE(&haudio_in_sai);
Jerome Coutant 0:146cf26a9bbb 1600 }
Jerome Coutant 0:146cf26a9bbb 1601
Jerome Coutant 0:146cf26a9bbb 1602 /**
Jerome Coutant 0:146cf26a9bbb 1603 * @brief De-initializes the output Audio Codec audio interface (SAI).
Jerome Coutant 0:146cf26a9bbb 1604 * @retval None
Jerome Coutant 0:146cf26a9bbb 1605 */
Jerome Coutant 0:146cf26a9bbb 1606 static void SAIx_In_DeInit(SAI_HandleTypeDef *hsai)
Jerome Coutant 0:146cf26a9bbb 1607 {
Jerome Coutant 0:146cf26a9bbb 1608 /* Disable SAI peripheral */
Jerome Coutant 0:146cf26a9bbb 1609 __HAL_SAI_DISABLE(hsai);
Jerome Coutant 0:146cf26a9bbb 1610
Jerome Coutant 0:146cf26a9bbb 1611 HAL_SAI_DeInit(hsai);
Jerome Coutant 0:146cf26a9bbb 1612 }
Jerome Coutant 0:146cf26a9bbb 1613
Jerome Coutant 0:146cf26a9bbb 1614 /**
Jerome Coutant 0:146cf26a9bbb 1615 * @}
Jerome Coutant 0:146cf26a9bbb 1616 */
Jerome Coutant 0:146cf26a9bbb 1617
Jerome Coutant 0:146cf26a9bbb 1618 /**
Jerome Coutant 0:146cf26a9bbb 1619 * @}
Jerome Coutant 0:146cf26a9bbb 1620 */
Jerome Coutant 0:146cf26a9bbb 1621
Jerome Coutant 0:146cf26a9bbb 1622 /**
Jerome Coutant 0:146cf26a9bbb 1623 * @}
Jerome Coutant 0:146cf26a9bbb 1624 */
Jerome Coutant 0:146cf26a9bbb 1625
Jerome Coutant 0:146cf26a9bbb 1626 /**
Jerome Coutant 0:146cf26a9bbb 1627 * @}
Jerome Coutant 0:146cf26a9bbb 1628 */
Jerome Coutant 0:146cf26a9bbb 1629
Jerome Coutant 0:146cf26a9bbb 1630 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/