BSP files for STM32H747I-Discovery Copy from ST Cube delivery

Dependents:   DISCO_H747I_LCD_demo DISCO_H747I_AUDIO_demo

Committer:
Jerome Coutant
Date:
Wed Nov 06 11:32:01 2019 +0100
Revision:
3:bc403474b366
Parent:
2:53134782cc12
Add PDM lib

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