BSP driver for DISCO_L496AG

Dependents:   DISCO_L496AG-LCD-prova_1 DISCO_L496AG-LCD-prova_2 DISCO_L496AG-LCD-demo DISCO_L496AG-SRAM-demo

Committer:
Jerome Coutant
Date:
Wed Nov 20 16:48:24 2019 +0100
Revision:
2:106c7b82e064
Parent:
0:d83f1c8ca282
Update BSP files with CubeL4 V1.14.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bcostm 0:d83f1c8ca282 1 /**
bcostm 0:d83f1c8ca282 2 ******************************************************************************
bcostm 0:d83f1c8ca282 3 * @file stm32l496g_discovery_audio.c
bcostm 0:d83f1c8ca282 4 * @author MCD Application Team
bcostm 0:d83f1c8ca282 5 * @brief This file provides a set of functions needed to manage the
bcostm 0:d83f1c8ca282 6 * Audio driver for the STM32L496G-Discovery board.
bcostm 0:d83f1c8ca282 7 ******************************************************************************
bcostm 0:d83f1c8ca282 8 * @attention
bcostm 0:d83f1c8ca282 9 *
Jerome Coutant 2:106c7b82e064 10 * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
Jerome Coutant 2:106c7b82e064 11 * All rights reserved.</center></h2>
bcostm 0:d83f1c8ca282 12 *
Jerome Coutant 2:106c7b82e064 13 * This software component is licensed by ST under BSD 3-Clause license,
Jerome Coutant 2:106c7b82e064 14 * the "License"; You may not use this file except in compliance with the
Jerome Coutant 2:106c7b82e064 15 * License. You may obtain a copy of the License at:
Jerome Coutant 2:106c7b82e064 16 * opensource.org/licenses/BSD-3-Clause
bcostm 0:d83f1c8ca282 17 *
bcostm 0:d83f1c8ca282 18 ******************************************************************************
bcostm 0:d83f1c8ca282 19 */
bcostm 0:d83f1c8ca282 20
bcostm 0:d83f1c8ca282 21 /*==============================================================================
bcostm 0:d83f1c8ca282 22 User NOTES
bcostm 0:d83f1c8ca282 23
bcostm 0:d83f1c8ca282 24 1. How To use this driver:
bcostm 0:d83f1c8ca282 25 --------------------------
bcostm 0:d83f1c8ca282 26 + This driver supports STM32L4xx devices on STM32L496G-Discovery (MB1261) Discovery boards.
bcostm 0:d83f1c8ca282 27 a) to play an audio file through headset. All functions names start by BSP_AUDIO_OUT_xxx.
bcostm 0:d83f1c8ca282 28 b) to record an audio file through digital microphones (MP34DT01TR ST mems)
bcostm 0:d83f1c8ca282 29 or analog microphone (headset microphone). All functions names start by BSP_AUDIO_IN_xxx.
bcostm 0:d83f1c8ca282 30
bcostm 0:d83f1c8ca282 31 a) PLAY A FILE:
bcostm 0:d83f1c8ca282 32 ==============
bcostm 0:d83f1c8ca282 33 + Call the function BSP_AUDIO_OUT_Init(
bcostm 0:d83f1c8ca282 34 OutputDevice: physical output mode (only OUTPUT_DEVICE_HEADPHONE).
bcostm 0:d83f1c8ca282 35 Volume : Initial volume to be set (0 is min (mute), 100 is max (100%)
bcostm 0:d83f1c8ca282 36 AudioFreq : Audio frequency in Hz (8000, 16000, 22500, 32000...)
bcostm 0:d83f1c8ca282 37 this parameter is relative to the audio file/stream type.
bcostm 0:d83f1c8ca282 38 )
bcostm 0:d83f1c8ca282 39 This function configures all the hardware required for the audio application (codec, I2C, SAI,
bcostm 0:d83f1c8ca282 40 GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if configuration is OK.
bcostm 0:d83f1c8ca282 41 If the returned value is different from AUDIO_OK or the function is stuck then the communication with
bcostm 0:d83f1c8ca282 42 the audio codec has failed.
bcostm 0:d83f1c8ca282 43 - OUTPUT_DEVICE_HEADPHONE: only Headphone output is available on this board.
bcostm 0:d83f1c8ca282 44
bcostm 0:d83f1c8ca282 45 + Call the function BSP_AUDIO_OUT_RegisterCallbacks to register user callbacks
bcostm 0:d83f1c8ca282 46 required to manage audio data streaming towards the audio codec (ErrorCallback(),
bcostm 0:d83f1c8ca282 47 HalfTransfer_CallBack() and TransferComplete_CallBack()).
bcostm 0:d83f1c8ca282 48
bcostm 0:d83f1c8ca282 49 + Call the function BSP_AUDIO_OUT_Play() to start audio playback (for the first time).
bcostm 0:d83f1c8ca282 50 + Call the function BSP_AUDIO_OUT_Pause() to pause audio playback.
bcostm 0:d83f1c8ca282 51 + Call the function BSP_AUDIO_OUT_Resume() to resume audio playback.
bcostm 0:d83f1c8ca282 52 Note. After calling BSP_AUDIO_OUT_Pause() function for pause, only BSP_AUDIO_OUT_Resume() should be called
bcostm 0:d83f1c8ca282 53 for resume (it is not allowed to call BSP_AUDIO_OUT_Play() in this case).
bcostm 0:d83f1c8ca282 54 Note. This function should be called only when the audio file is played or paused (not stopped).
bcostm 0:d83f1c8ca282 55 + Call the function BSP_AUDIO_OUT_Stop() to stop audio playback.
bcostm 0:d83f1c8ca282 56 + To modify the volume level, the sampling frequency, the device output mode,
bcostm 0:d83f1c8ca282 57 the mute status or the audio configuration or the stop, use the functions: BSP_AUDIO_OUT_SetVolume(),
bcostm 0:d83f1c8ca282 58 AUDIO_OUT_SetFrequency(), BSP_AUDIO_OUT_SetOutputMode(), BSP_AUDIO_OUT_SetMute()and
bcostm 0:d83f1c8ca282 59 BSP_AUDIO_OUT_ChangeAudioConfig().
bcostm 0:d83f1c8ca282 60
bcostm 0:d83f1c8ca282 61 Driver architecture:
bcostm 0:d83f1c8ca282 62 --------------------
bcostm 0:d83f1c8ca282 63 + This driver provides the audio layer high level API: it consists in functions
bcostm 0:d83f1c8ca282 64 exported in the stm32l496g_discovery_audio.h file (e.g. BSP_AUDIO_OUT_Init(),
bcostm 0:d83f1c8ca282 65 BSP_AUDIO_OUT_Play(), ...).
bcostm 0:d83f1c8ca282 66 + This driver also includes the Media Access Layer (MAL): it consists in
bcostm 0:d83f1c8ca282 67 functions allowing to access setup the audio devices. These functions
bcostm 0:d83f1c8ca282 68 are included as local functions into the stm32l496g_discovery_audio.c file
bcostm 0:d83f1c8ca282 69 (e.g. AUDIO_SAIx_Init()).
bcostm 0:d83f1c8ca282 70
bcostm 0:d83f1c8ca282 71 Known Limitations:
bcostm 0:d83f1c8ca282 72 ------------------
bcostm 0:d83f1c8ca282 73 1- Communication with the audio codec (through I2C) may be corrupted if it is interrupted by some
bcostm 0:d83f1c8ca282 74 user interrupt routines (in this case, interrupts could be disabled just before the start of
bcostm 0:d83f1c8ca282 75 communication then re-enabled when it is over). Note that this communication is only done at
bcostm 0:d83f1c8ca282 76 the configuration phase (BSP_AUDIO_OUT_Init() or BSP_AUDIO_OUT_Stop()) and when Volume control modification is
bcostm 0:d83f1c8ca282 77 performed (BSP_AUDIO_OUT_SetVolume() or BSP_AUDIO_OUT_SetMute()or BSP_AUDIO_OUT_SetOutputMode()).
bcostm 0:d83f1c8ca282 78 When the audio data is played, no communication is required with the audio codec.
bcostm 0:d83f1c8ca282 79 2- Parsing of audio file is not implemented (in order to determine audio file properties: Mono/Stereo, Data size,
bcostm 0:d83f1c8ca282 80 File size, Audio Frequency, Audio Data header size ...). The configuration is fixed for the given audio file.
bcostm 0:d83f1c8ca282 81 3- Supports only 16-bits audio data size.
bcostm 0:d83f1c8ca282 82
bcostm 0:d83f1c8ca282 83 b) RECORD A FILE:
bcostm 0:d83f1c8ca282 84 ================
bcostm 0:d83f1c8ca282 85 + Call the function BSP_AUDIO_IN_InitEx(
bcostm 0:d83f1c8ca282 86 InputDevice: physical input mode (INPUT_DEVICE_DIGITAL_MIC
bcostm 0:d83f1c8ca282 87 INPUT_DEVICE_DIGITAL_MIC1, INPUT_DEVICE_DIGITAL_MIC2
bcostm 0:d83f1c8ca282 88 or INPUT_DEVICE_ANALOG_MIC)
bcostm 0:d83f1c8ca282 89 AudioFreq: Audio frequency in Hz (8000, 16000, 22500, 32000 ...)
bcostm 0:d83f1c8ca282 90 )
bcostm 0:d83f1c8ca282 91 This function configures all the hardware required for the audio application (DFSDM or SAI,
bcostm 0:d83f1c8ca282 92 GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if the
bcostm 0:d83f1c8ca282 93 configuration completes successfully.
bcostm 0:d83f1c8ca282 94 - INPUT_DEVICE_DIGITAL_MIC: Record from digital microphones mounted on board.
bcostm 0:d83f1c8ca282 95 - INPUT_DEVICE_DIGITAL_MIC1: Record from digital microphone 1 mounted on board (left microphone).
bcostm 0:d83f1c8ca282 96 - INPUT_DEVICE_DIGITAL_MIC2: Record from digital microphone 2 mounted on board (right microphone).
bcostm 0:d83f1c8ca282 97 - INPUT_DEVICE_ANALOG_MIC: Record from headset microphone.
bcostm 0:d83f1c8ca282 98
bcostm 0:d83f1c8ca282 99 + Call the function BSP_AUDIO_IN_RegisterCallbacks to register user callbacks
bcostm 0:d83f1c8ca282 100 used to stream audio data toward the record buffer (ErrorCallback(),
bcostm 0:d83f1c8ca282 101 HalfTransfer_CallBack() and TransferComplete_CallBack()).
bcostm 0:d83f1c8ca282 102
bcostm 0:d83f1c8ca282 103 + Call the function BSP_AUDIO_IN_Record(
bcostm 0:d83f1c8ca282 104 pbuf Main buffer pointer for the recorded data storing
bcostm 0:d83f1c8ca282 105 size Current size of the recorded buffer
bcostm 0:d83f1c8ca282 106 )
bcostm 0:d83f1c8ca282 107 to start recording from the microphone.
bcostm 0:d83f1c8ca282 108
bcostm 0:d83f1c8ca282 109 + Call the function BSP_AUDIO_IN_STOP() to stop recording.
bcostm 0:d83f1c8ca282 110 ==============================================================================*/
bcostm 0:d83f1c8ca282 111
bcostm 0:d83f1c8ca282 112 /* Includes ------------------------------------------------------------------*/
bcostm 0:d83f1c8ca282 113 #include <string.h>
bcostm 0:d83f1c8ca282 114 #include "stm32l496g_discovery_audio.h"
bcostm 0:d83f1c8ca282 115
bcostm 0:d83f1c8ca282 116 /** @addtogroup BSP
bcostm 0:d83f1c8ca282 117 * @{
bcostm 0:d83f1c8ca282 118 */
bcostm 0:d83f1c8ca282 119
bcostm 0:d83f1c8ca282 120 /** @addtogroup STM32L496G_DISCOVERY
bcostm 0:d83f1c8ca282 121 * @{
bcostm 0:d83f1c8ca282 122 */
bcostm 0:d83f1c8ca282 123
bcostm 0:d83f1c8ca282 124 /** @defgroup STM32L496G_DISCOVERY_AUDIO STM32L496G-DISCOVERY AUDIO
bcostm 0:d83f1c8ca282 125 * @brief This file includes the low layer driver for cs42l51 Audio Codec
bcostm 0:d83f1c8ca282 126 * available on STM32L496G-Discovery board (MB1261).
bcostm 0:d83f1c8ca282 127 * @{
bcostm 0:d83f1c8ca282 128 */
bcostm 0:d83f1c8ca282 129
bcostm 0:d83f1c8ca282 130 /* Private typedef -----------------------------------------------------------*/
bcostm 0:d83f1c8ca282 131 /** @defgroup STM32L496G_DISCOVERY_AUDIO_Private_Types Private Types
bcostm 0:d83f1c8ca282 132 * @{
bcostm 0:d83f1c8ca282 133 */
bcostm 0:d83f1c8ca282 134 typedef struct
bcostm 0:d83f1c8ca282 135 {
bcostm 0:d83f1c8ca282 136 AUDIO_DrvTypeDef *AudioDrv; /* Audio codec driver */
bcostm 0:d83f1c8ca282 137 uint32_t OutputDevice; /* Output device */
bcostm 0:d83f1c8ca282 138 uint32_t Frequency; /* Playback frequency */
bcostm 0:d83f1c8ca282 139 uint32_t Volume; /* Playback volume */
bcostm 0:d83f1c8ca282 140 Audio_CallbackTypeDef CbError; /* pointer to the callback function invoked when error occurs */
bcostm 0:d83f1c8ca282 141 Audio_CallbackTypeDef CbHalfTransfer; /* pointer to the callback function invoked when half transfer occurs */
bcostm 0:d83f1c8ca282 142 Audio_CallbackTypeDef CbTransferComplete; /* pointer to the callback function invoked when transfer complete occurs */
bcostm 0:d83f1c8ca282 143 } AUDIO_OUT_TypeDef;
bcostm 0:d83f1c8ca282 144
bcostm 0:d83f1c8ca282 145 typedef struct
bcostm 0:d83f1c8ca282 146 {
bcostm 0:d83f1c8ca282 147 AUDIO_DrvTypeDef *AudioDrv; /* Audio codec driver */
bcostm 0:d83f1c8ca282 148 DFSDM_Channel_HandleTypeDef hDfsdmLeftChannel; /* DFSDM channel handle used for left channel */
bcostm 0:d83f1c8ca282 149 DFSDM_Channel_HandleTypeDef hDfsdmRightChannel; /* DFSDM channel handle used for right channel */
bcostm 0:d83f1c8ca282 150 DMA_HandleTypeDef hDmaDfsdmLeft; /* DMA handle used for DFSDM regular conversions on left channel */
bcostm 0:d83f1c8ca282 151 DMA_HandleTypeDef hDmaDfsdmRight; /* DMA handle used for DFSDM regular conversions on right channel */
bcostm 0:d83f1c8ca282 152 int32_t *LeftRecBuff; /* Buffers for left samples */
bcostm 0:d83f1c8ca282 153 int32_t *RightRecBuff; /* Buffers for right samples */
bcostm 0:d83f1c8ca282 154 uint32_t InputDevice; /* Input device */
bcostm 0:d83f1c8ca282 155 uint32_t Frequency; /* Record Frequency */
bcostm 0:d83f1c8ca282 156 uint32_t BitResolution; /* Record bit resolution */
bcostm 0:d83f1c8ca282 157 uint32_t ChannelNbr; /* Record Channel Number */
bcostm 0:d83f1c8ca282 158 uint16_t *pRecBuf; /* Pointer to record user buffer */
bcostm 0:d83f1c8ca282 159 uint32_t RecSize; /* Size to record in mono, double size to record in stereo */
bcostm 0:d83f1c8ca282 160 Audio_CallbackTypeDef CbError; /* pointer to the callback function invoked when a DMA transfer fails */
bcostm 0:d83f1c8ca282 161 Audio_CallbackTypeDef CbHalfTransfer; /* pointer to the callback function invoked when half of the DMA transfer is completed */
bcostm 0:d83f1c8ca282 162 Audio_CallbackTypeDef CbTransferComplete; /* pointer to the callback function invoked when the DMA transfer is completed */
bcostm 0:d83f1c8ca282 163 } AUDIO_IN_TypeDef;
bcostm 0:d83f1c8ca282 164
bcostm 0:d83f1c8ca282 165 /**
bcostm 0:d83f1c8ca282 166 * @}
bcostm 0:d83f1c8ca282 167 */
bcostm 0:d83f1c8ca282 168
bcostm 0:d83f1c8ca282 169 /* Private defines ------------------------------------------------------------*/
bcostm 0:d83f1c8ca282 170 /** @defgroup STM32L496G_DISCOVERY_AUDIO_Private_Constants Private Constants
bcostm 0:d83f1c8ca282 171 * @{
bcostm 0:d83f1c8ca282 172 */
bcostm 0:d83f1c8ca282 173 /**
bcostm 0:d83f1c8ca282 174 * @}
bcostm 0:d83f1c8ca282 175 */
bcostm 0:d83f1c8ca282 176
bcostm 0:d83f1c8ca282 177 /* Private macros ------------------------------------------------------------*/
bcostm 0:d83f1c8ca282 178 /** @defgroup STM32L496G_DISCOVERY_AUDIO_Private_Macros Private Macros
bcostm 0:d83f1c8ca282 179 * @{
bcostm 0:d83f1c8ca282 180 */
bcostm 0:d83f1c8ca282 181 /*### PLAY ###*/
bcostm 0:d83f1c8ca282 182 /* SCK(kHz) = SAI_CK_x/(SAIClockDivider*2*256) */
bcostm 0:d83f1c8ca282 183 #define SAIClockDivider(__FREQUENCY__) \
bcostm 0:d83f1c8ca282 184 (__FREQUENCY__ == AUDIO_FREQUENCY_8K) ? 12 \
bcostm 0:d83f1c8ca282 185 : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 2 \
bcostm 0:d83f1c8ca282 186 : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 6 \
bcostm 0:d83f1c8ca282 187 : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 1 \
bcostm 0:d83f1c8ca282 188 : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 3 \
bcostm 0:d83f1c8ca282 189 : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 0 \
bcostm 0:d83f1c8ca282 190 : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 2 : 1 \
bcostm 0:d83f1c8ca282 191
bcostm 0:d83f1c8ca282 192 /*### RECORD ###*/
bcostm 0:d83f1c8ca282 193 #define DFSDMOverSampling(__FREQUENCY__) \
bcostm 0:d83f1c8ca282 194 (__FREQUENCY__ == AUDIO_FREQUENCY_8K) ? 256 \
bcostm 0:d83f1c8ca282 195 : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 256 \
bcostm 0:d83f1c8ca282 196 : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 128 \
bcostm 0:d83f1c8ca282 197 : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 128 \
bcostm 0:d83f1c8ca282 198 : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 64 \
bcostm 0:d83f1c8ca282 199 : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 64 \
bcostm 0:d83f1c8ca282 200 : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 32 : 16 \
bcostm 0:d83f1c8ca282 201
bcostm 0:d83f1c8ca282 202 #define DFSDMClockDivider(__FREQUENCY__) \
bcostm 0:d83f1c8ca282 203 (__FREQUENCY__ == AUDIO_FREQUENCY_8K) ? 24 \
bcostm 0:d83f1c8ca282 204 : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 4 \
bcostm 0:d83f1c8ca282 205 : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 24 \
bcostm 0:d83f1c8ca282 206 : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 4 \
bcostm 0:d83f1c8ca282 207 : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 24 \
bcostm 0:d83f1c8ca282 208 : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 4 \
bcostm 0:d83f1c8ca282 209 : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 32 : 32 \
bcostm 0:d83f1c8ca282 210
bcostm 0:d83f1c8ca282 211 #define DFSDMFilterOrder(__FREQUENCY__) \
bcostm 0:d83f1c8ca282 212 (__FREQUENCY__ == AUDIO_FREQUENCY_8K) ? DFSDM_FILTER_SINC3_ORDER \
bcostm 0:d83f1c8ca282 213 : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? DFSDM_FILTER_SINC3_ORDER \
bcostm 0:d83f1c8ca282 214 : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? DFSDM_FILTER_SINC3_ORDER \
bcostm 0:d83f1c8ca282 215 : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? DFSDM_FILTER_SINC3_ORDER \
bcostm 0:d83f1c8ca282 216 : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? DFSDM_FILTER_SINC4_ORDER \
bcostm 0:d83f1c8ca282 217 : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? DFSDM_FILTER_SINC3_ORDER \
bcostm 0:d83f1c8ca282 218 : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? DFSDM_FILTER_SINC4_ORDER : DFSDM_FILTER_SINC5_ORDER \
bcostm 0:d83f1c8ca282 219
bcostm 0:d83f1c8ca282 220 #define DFSDMRightBitShift(__FREQUENCY__) \
bcostm 0:d83f1c8ca282 221 (__FREQUENCY__ == AUDIO_FREQUENCY_8K) ? 8 \
bcostm 0:d83f1c8ca282 222 : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 8 \
bcostm 0:d83f1c8ca282 223 : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 6 \
bcostm 0:d83f1c8ca282 224 : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 6 \
bcostm 0:d83f1c8ca282 225 : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 8 \
bcostm 0:d83f1c8ca282 226 : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 2 \
bcostm 0:d83f1c8ca282 227 : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 4 : 4 \
bcostm 0:d83f1c8ca282 228
bcostm 0:d83f1c8ca282 229 /* Saturate the record PCM sample */
bcostm 0:d83f1c8ca282 230 #define SaturaLH(N, L, H) (((N)<(L))?(L):(((N)>(H))?(H):(N)))
bcostm 0:d83f1c8ca282 231
bcostm 0:d83f1c8ca282 232 /**
bcostm 0:d83f1c8ca282 233 * @}
bcostm 0:d83f1c8ca282 234 */
bcostm 0:d83f1c8ca282 235
bcostm 0:d83f1c8ca282 236 /* Private variables ---------------------------------------------------------*/
bcostm 0:d83f1c8ca282 237 /** @defgroup STM32L496G_DISCOVERY_AUDIO_Private_Variables Private Variables
bcostm 0:d83f1c8ca282 238 * @{
bcostm 0:d83f1c8ca282 239 */
bcostm 0:d83f1c8ca282 240 /* Audio output context information */
bcostm 0:d83f1c8ca282 241 static AUDIO_OUT_TypeDef hAudioOut = {0};
bcostm 0:d83f1c8ca282 242
bcostm 0:d83f1c8ca282 243 /* Audio input context information */
bcostm 0:d83f1c8ca282 244 static AUDIO_IN_TypeDef hAudioIn = {0};
bcostm 0:d83f1c8ca282 245
bcostm 0:d83f1c8ca282 246 /* SAI DMA handle */
bcostm 0:d83f1c8ca282 247 static DMA_HandleTypeDef hDmaSaiTx;
bcostm 0:d83f1c8ca282 248 static DMA_HandleTypeDef hDmaSaiRx;
bcostm 0:d83f1c8ca282 249
bcostm 0:d83f1c8ca282 250 static uint32_t DmaLeftRecHalfBuffCplt;
bcostm 0:d83f1c8ca282 251 static uint32_t DmaLeftRecBuffCplt;
bcostm 0:d83f1c8ca282 252 static uint32_t DmaRightRecHalfBuffCplt;
bcostm 0:d83f1c8ca282 253 static uint32_t DmaRightRecBuffCplt;
bcostm 0:d83f1c8ca282 254
bcostm 0:d83f1c8ca282 255
bcostm 0:d83f1c8ca282 256 /**
bcostm 0:d83f1c8ca282 257 * @}
bcostm 0:d83f1c8ca282 258 */
bcostm 0:d83f1c8ca282 259
bcostm 0:d83f1c8ca282 260 /* Exported variables ---------------------------------------------------------*/
bcostm 0:d83f1c8ca282 261 /** @defgroup STM32L496G_DISCOVERY_AUDIO_Exported_Variables Exported Variables
bcostm 0:d83f1c8ca282 262 * @{
bcostm 0:d83f1c8ca282 263 */
bcostm 0:d83f1c8ca282 264 /* SAIx handle */
bcostm 0:d83f1c8ca282 265 SAI_HandleTypeDef BSP_AUDIO_hSai_Tx;
bcostm 0:d83f1c8ca282 266 SAI_HandleTypeDef BSP_AUDIO_hSai_Rx;
bcostm 0:d83f1c8ca282 267
bcostm 0:d83f1c8ca282 268 /* DFSDM filter handle */
bcostm 0:d83f1c8ca282 269 DFSDM_Filter_HandleTypeDef BSP_AUDIO_hDfsdmLeftFilter;
bcostm 0:d83f1c8ca282 270 DFSDM_Filter_HandleTypeDef BSP_AUDIO_hDfsdmRightFilter;
bcostm 0:d83f1c8ca282 271 /**
bcostm 0:d83f1c8ca282 272 * @}
bcostm 0:d83f1c8ca282 273 */
bcostm 0:d83f1c8ca282 274
bcostm 0:d83f1c8ca282 275 /* Private function prototypes -----------------------------------------------*/
bcostm 0:d83f1c8ca282 276 /** @defgroup STM32L496G_DISCOVERY_AUDIO_Private_Functions Private Functions
bcostm 0:d83f1c8ca282 277 * @{
bcostm 0:d83f1c8ca282 278 */
bcostm 0:d83f1c8ca282 279 static uint8_t AUDIO_SAIx_Init(uint32_t AudioFreq);
bcostm 0:d83f1c8ca282 280 static uint8_t AUDIO_SAIx_DeInit(void);
bcostm 0:d83f1c8ca282 281 static uint8_t AUDIO_DFSDMx_Init(uint32_t AudioFreq);
bcostm 0:d83f1c8ca282 282 static uint8_t AUDIO_DFSDMx_DeInit(void);
bcostm 0:d83f1c8ca282 283 static uint8_t AUDIO_SAIPLLConfig(uint32_t AudioFreq);
bcostm 0:d83f1c8ca282 284 /**
bcostm 0:d83f1c8ca282 285 * @}
bcostm 0:d83f1c8ca282 286 */
bcostm 0:d83f1c8ca282 287
bcostm 0:d83f1c8ca282 288 /* Exported functions --------------------------------------------------------*/
bcostm 0:d83f1c8ca282 289 /** @addtogroup STM32L496G_DISCOVERY_AUDIO_Exported_Functions
bcostm 0:d83f1c8ca282 290 * @{
bcostm 0:d83f1c8ca282 291 */
bcostm 0:d83f1c8ca282 292
bcostm 0:d83f1c8ca282 293 /**
bcostm 0:d83f1c8ca282 294 * @brief Configures the audio codec related peripherals.
bcostm 0:d83f1c8ca282 295 * @param OutputDevice: OUTPUT_DEVICE_HEADPHONE.
bcostm 0:d83f1c8ca282 296 * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max))
bcostm 0:d83f1c8ca282 297 * @param AudioFreq: Audio frequency used to play the audio stream.
bcostm 0:d83f1c8ca282 298 * @retval BSP AUDIO status
bcostm 0:d83f1c8ca282 299 * @note The SAI PLL input clock must be configure in the user application.
bcostm 0:d83f1c8ca282 300 * The SAI PLL configuration done within this function assumes that
bcostm 0:d83f1c8ca282 301 * the SAI PLL input clock runs at 8 MHz.
bcostm 0:d83f1c8ca282 302 */
bcostm 0:d83f1c8ca282 303 uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice,
bcostm 0:d83f1c8ca282 304 uint8_t Volume,
bcostm 0:d83f1c8ca282 305 uint32_t AudioFreq)
bcostm 0:d83f1c8ca282 306 {
bcostm 0:d83f1c8ca282 307 /* Initialize the audio output context */
bcostm 0:d83f1c8ca282 308 hAudioOut.AudioDrv = &cs42l51_drv;
bcostm 0:d83f1c8ca282 309 hAudioOut.OutputDevice = OutputDevice;
bcostm 0:d83f1c8ca282 310 hAudioOut.Frequency = AudioFreq;
bcostm 0:d83f1c8ca282 311 hAudioOut.Volume = Volume;
bcostm 0:d83f1c8ca282 312 hAudioOut.CbError = (Audio_CallbackTypeDef)NULL;
bcostm 0:d83f1c8ca282 313 hAudioOut.CbHalfTransfer = (Audio_CallbackTypeDef)NULL;
bcostm 0:d83f1c8ca282 314 hAudioOut.CbTransferComplete = (Audio_CallbackTypeDef)NULL;
bcostm 0:d83f1c8ca282 315
bcostm 0:d83f1c8ca282 316 /* Check if input device is currently used */
bcostm 0:d83f1c8ca282 317 if (hAudioIn.InputDevice != 0)
bcostm 0:d83f1c8ca282 318 {
bcostm 0:d83f1c8ca282 319 /* If input device is currently used, SAI PLL is already initialized */
bcostm 0:d83f1c8ca282 320 /* Check that AudioFreq for record and playback is the same */
bcostm 0:d83f1c8ca282 321 if (hAudioIn.Frequency != hAudioOut.Frequency)
bcostm 0:d83f1c8ca282 322 {
bcostm 0:d83f1c8ca282 323 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 324 }
bcostm 0:d83f1c8ca282 325 }
bcostm 0:d83f1c8ca282 326 else
bcostm 0:d83f1c8ca282 327 {
bcostm 0:d83f1c8ca282 328 /* Configure the SAI PLL according to the requested audio frequency */
bcostm 0:d83f1c8ca282 329 if (AUDIO_SAIPLLConfig(AudioFreq) != AUDIO_OK)
bcostm 0:d83f1c8ca282 330 {
bcostm 0:d83f1c8ca282 331 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 332 }
bcostm 0:d83f1c8ca282 333 }
bcostm 0:d83f1c8ca282 334
bcostm 0:d83f1c8ca282 335 /* If input device is analogic mic, SAI is already initialized */
bcostm 0:d83f1c8ca282 336 if (hAudioIn.InputDevice != INPUT_DEVICE_ANALOG_MIC)
bcostm 0:d83f1c8ca282 337 {
bcostm 0:d83f1c8ca282 338 /* SAI data transfer preparation: prepare the Media to be used for the audio
bcostm 0:d83f1c8ca282 339 transfer from memory to SAI peripheral. */
bcostm 0:d83f1c8ca282 340 if (AUDIO_SAIx_Init(AudioFreq) != AUDIO_OK)
bcostm 0:d83f1c8ca282 341 {
bcostm 0:d83f1c8ca282 342 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 343 }
bcostm 0:d83f1c8ca282 344 }
bcostm 0:d83f1c8ca282 345
bcostm 0:d83f1c8ca282 346 /* Initialize the audio codec internal registers */
bcostm 0:d83f1c8ca282 347 if (hAudioOut.AudioDrv->Init(AUDIO_I2C_ADDRESS,
bcostm 0:d83f1c8ca282 348 (hAudioOut.OutputDevice | hAudioIn.InputDevice),
bcostm 0:d83f1c8ca282 349 Volume,
bcostm 0:d83f1c8ca282 350 AudioFreq) != 0)
bcostm 0:d83f1c8ca282 351 {
bcostm 0:d83f1c8ca282 352 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 353 }
bcostm 0:d83f1c8ca282 354
bcostm 0:d83f1c8ca282 355 return AUDIO_OK;
bcostm 0:d83f1c8ca282 356 }
bcostm 0:d83f1c8ca282 357
bcostm 0:d83f1c8ca282 358 /**
bcostm 0:d83f1c8ca282 359 * @brief De-Initializes audio codec related peripherals
bcostm 0:d83f1c8ca282 360 * @retval BSP AUDIO status
bcostm 0:d83f1c8ca282 361
bcostm 0:d83f1c8ca282 362 */
bcostm 0:d83f1c8ca282 363 uint8_t BSP_AUDIO_OUT_DeInit(void)
bcostm 0:d83f1c8ca282 364 {
bcostm 0:d83f1c8ca282 365 if (hAudioIn.InputDevice == INPUT_DEVICE_ANALOG_MIC)
bcostm 0:d83f1c8ca282 366 {
bcostm 0:d83f1c8ca282 367 /* Reset playback path on audio codec */
bcostm 0:d83f1c8ca282 368 if (hAudioIn.AudioDrv->Init(AUDIO_I2C_ADDRESS,
bcostm 0:d83f1c8ca282 369 hAudioIn.InputDevice,
bcostm 0:d83f1c8ca282 370 (uint8_t) hAudioOut.Volume,
bcostm 0:d83f1c8ca282 371 hAudioIn.Frequency) != 0)
bcostm 0:d83f1c8ca282 372 {
bcostm 0:d83f1c8ca282 373 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 374 }
bcostm 0:d83f1c8ca282 375 }
bcostm 0:d83f1c8ca282 376 else
bcostm 0:d83f1c8ca282 377 {
bcostm 0:d83f1c8ca282 378 /* De-initializes SAI interface */
bcostm 0:d83f1c8ca282 379 if (AUDIO_SAIx_DeInit() != AUDIO_OK)
bcostm 0:d83f1c8ca282 380 {
bcostm 0:d83f1c8ca282 381 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 382 }
bcostm 0:d83f1c8ca282 383
bcostm 0:d83f1c8ca282 384 /* DeInit audio codec */
bcostm 0:d83f1c8ca282 385 hAudioOut.AudioDrv->DeInit();
bcostm 0:d83f1c8ca282 386 }
bcostm 0:d83f1c8ca282 387
bcostm 0:d83f1c8ca282 388 /* Disable SAI PLL if no more device is used */
bcostm 0:d83f1c8ca282 389 if (hAudioIn.InputDevice == 0)
bcostm 0:d83f1c8ca282 390 {
bcostm 0:d83f1c8ca282 391 if (AUDIO_SAIx_PLL_DISABLE() != AUDIO_OK)
bcostm 0:d83f1c8ca282 392 {
bcostm 0:d83f1c8ca282 393 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 394 }
bcostm 0:d83f1c8ca282 395 }
bcostm 0:d83f1c8ca282 396
bcostm 0:d83f1c8ca282 397 /* Reset the audio output context */
bcostm 0:d83f1c8ca282 398 memset(&hAudioOut, 0, sizeof(hAudioOut));
bcostm 0:d83f1c8ca282 399
bcostm 0:d83f1c8ca282 400 return AUDIO_OK;
bcostm 0:d83f1c8ca282 401 }
bcostm 0:d83f1c8ca282 402
bcostm 0:d83f1c8ca282 403 /**
bcostm 0:d83f1c8ca282 404 * @brief Starts playing audio stream from a data buffer for a determined size.
bcostm 0:d83f1c8ca282 405 * @param pData: pointer on PCM samples buffer
bcostm 0:d83f1c8ca282 406 * @param Size: Number of audio data HALF WORD.
bcostm 0:d83f1c8ca282 407 * @retval BSP AUDIO status
bcostm 0:d83f1c8ca282 408 */
bcostm 0:d83f1c8ca282 409 uint8_t BSP_AUDIO_OUT_Play(uint16_t *pData, uint32_t Size)
bcostm 0:d83f1c8ca282 410 {
bcostm 0:d83f1c8ca282 411 /* Initiate a DMA transfer of PCM samples towards the serial audio interface */
bcostm 0:d83f1c8ca282 412 if (HAL_SAI_Transmit_DMA(&BSP_AUDIO_hSai_Tx, (uint8_t *)pData, DMA_MAX(Size)) != HAL_OK)
bcostm 0:d83f1c8ca282 413 {
bcostm 0:d83f1c8ca282 414 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 415 }
bcostm 0:d83f1c8ca282 416
bcostm 0:d83f1c8ca282 417 /* Call the audio Codec Play function */
bcostm 0:d83f1c8ca282 418 if (hAudioOut.AudioDrv->Play(AUDIO_I2C_ADDRESS, pData, Size) != 0)
bcostm 0:d83f1c8ca282 419 {
bcostm 0:d83f1c8ca282 420 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 421 }
bcostm 0:d83f1c8ca282 422
bcostm 0:d83f1c8ca282 423 return AUDIO_OK;
bcostm 0:d83f1c8ca282 424 }
bcostm 0:d83f1c8ca282 425
bcostm 0:d83f1c8ca282 426 /**
bcostm 0:d83f1c8ca282 427 * @brief Sends n-Bytes on the SAI interface.
bcostm 0:d83f1c8ca282 428 * @param pData: pointer on PCM samples buffer
bcostm 0:d83f1c8ca282 429 * @param Size: number of data to be written
bcostm 0:d83f1c8ca282 430 * @retval BSP AUDIO status
bcostm 0:d83f1c8ca282 431 */
bcostm 0:d83f1c8ca282 432 uint8_t BSP_AUDIO_OUT_ChangeBuffer(uint16_t *pData, uint16_t Size)
bcostm 0:d83f1c8ca282 433 {
bcostm 0:d83f1c8ca282 434 /* Initiate a DMA transfer of PCM samples towards the serial audio interface */
bcostm 0:d83f1c8ca282 435 if (HAL_SAI_Transmit_DMA(&BSP_AUDIO_hSai_Tx, (uint8_t *)pData, Size) != HAL_OK)
bcostm 0:d83f1c8ca282 436 {
bcostm 0:d83f1c8ca282 437 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 438 }
bcostm 0:d83f1c8ca282 439
bcostm 0:d83f1c8ca282 440 return AUDIO_OK;
bcostm 0:d83f1c8ca282 441 }
bcostm 0:d83f1c8ca282 442
bcostm 0:d83f1c8ca282 443 /**
bcostm 0:d83f1c8ca282 444 * @brief This function Pauses the audio file stream. In case
bcostm 0:d83f1c8ca282 445 * of using DMA, the DMA Pause feature is used.
bcostm 0:d83f1c8ca282 446 * @note When calling BSP_AUDIO_OUT_Pause() function for pause, only
bcostm 0:d83f1c8ca282 447 * BSP_AUDIO_OUT_Resume() function should be called for resume
bcostm 0:d83f1c8ca282 448 * (use of BSP_AUDIO_OUT_Play() function for resume could lead
bcostm 0:d83f1c8ca282 449 * to unexpected behavior).
bcostm 0:d83f1c8ca282 450 * @retval BSP AUDIO status
bcostm 0:d83f1c8ca282 451 */
bcostm 0:d83f1c8ca282 452 uint8_t BSP_AUDIO_OUT_Pause(void)
bcostm 0:d83f1c8ca282 453 {
bcostm 0:d83f1c8ca282 454 /* Call the Audio Codec Pause function */
bcostm 0:d83f1c8ca282 455 if (hAudioOut.AudioDrv->Pause(AUDIO_I2C_ADDRESS) != 0)
bcostm 0:d83f1c8ca282 456 {
bcostm 0:d83f1c8ca282 457 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 458 }
bcostm 0:d83f1c8ca282 459
bcostm 0:d83f1c8ca282 460 /* Pause DMA transfer of PCM samples towards the serial audio interface */
bcostm 0:d83f1c8ca282 461 if (HAL_SAI_DMAPause(&BSP_AUDIO_hSai_Tx) != HAL_OK)
bcostm 0:d83f1c8ca282 462 {
bcostm 0:d83f1c8ca282 463 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 464 }
bcostm 0:d83f1c8ca282 465
bcostm 0:d83f1c8ca282 466 return AUDIO_OK;
bcostm 0:d83f1c8ca282 467 }
bcostm 0:d83f1c8ca282 468
bcostm 0:d83f1c8ca282 469 /**
bcostm 0:d83f1c8ca282 470 * @brief This function Resumes the audio file stream.
bcostm 0:d83f1c8ca282 471 * @note When calling BSP_AUDIO_OUT_Pause() function for pause, only
bcostm 0:d83f1c8ca282 472 * BSP_AUDIO_OUT_Resume() function should be called for resume
bcostm 0:d83f1c8ca282 473 * (use of BSP_AUDIO_OUT_Play() function for resume could lead to
bcostm 0:d83f1c8ca282 474 * unexpected behavior).
bcostm 0:d83f1c8ca282 475 * @retval BSP AUDIO status
bcostm 0:d83f1c8ca282 476 */
bcostm 0:d83f1c8ca282 477 uint8_t BSP_AUDIO_OUT_Resume(void)
bcostm 0:d83f1c8ca282 478 {
bcostm 0:d83f1c8ca282 479 /* Call the Audio Codec Resume function */
bcostm 0:d83f1c8ca282 480 if (hAudioOut.AudioDrv->Resume(AUDIO_I2C_ADDRESS) != 0)
bcostm 0:d83f1c8ca282 481 {
bcostm 0:d83f1c8ca282 482 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 483 }
bcostm 0:d83f1c8ca282 484
bcostm 0:d83f1c8ca282 485 /* Resume DMA transfer of PCM samples towards the serial audio interface */
bcostm 0:d83f1c8ca282 486 if (HAL_SAI_DMAResume(&BSP_AUDIO_hSai_Tx) != HAL_OK)
bcostm 0:d83f1c8ca282 487 {
bcostm 0:d83f1c8ca282 488 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 489 }
bcostm 0:d83f1c8ca282 490
bcostm 0:d83f1c8ca282 491 return AUDIO_OK;
bcostm 0:d83f1c8ca282 492 }
bcostm 0:d83f1c8ca282 493
bcostm 0:d83f1c8ca282 494 /**
bcostm 0:d83f1c8ca282 495 * @brief Stops audio playing and Power down the Audio Codec.
bcostm 0:d83f1c8ca282 496 * @param Option: could be one of the following parameters
bcostm 0:d83f1c8ca282 497 * - CODEC_PDWN_SW: for software power off (by writing registers).
bcostm 0:d83f1c8ca282 498 * Then no need to reconfigure the Codec after power on.
bcostm 0:d83f1c8ca282 499 * - CODEC_PDWN_HW: completely shut down the codec (physically).
bcostm 0:d83f1c8ca282 500 * Then need to reconfigure the Codec after power on.
bcostm 0:d83f1c8ca282 501 * @retval BSP AUDIO status
bcostm 0:d83f1c8ca282 502 */
bcostm 0:d83f1c8ca282 503 uint8_t BSP_AUDIO_OUT_Stop(uint32_t Option)
bcostm 0:d83f1c8ca282 504 {
bcostm 0:d83f1c8ca282 505 /* Prevent unused argument(s) compilation warning */
bcostm 0:d83f1c8ca282 506 UNUSED(Option);
bcostm 0:d83f1c8ca282 507
bcostm 0:d83f1c8ca282 508 /* Call Audio Codec Stop function */
bcostm 0:d83f1c8ca282 509 if (hAudioOut.AudioDrv->Stop(AUDIO_I2C_ADDRESS, Option) != 0)
bcostm 0:d83f1c8ca282 510 {
bcostm 0:d83f1c8ca282 511 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 512 }
bcostm 0:d83f1c8ca282 513
bcostm 0:d83f1c8ca282 514 /* Wait at least 100ms */
bcostm 0:d83f1c8ca282 515 HAL_Delay(100);
bcostm 0:d83f1c8ca282 516
bcostm 0:d83f1c8ca282 517 /* Stop DMA transfer of PCM samples towards the serial audio interface */
bcostm 0:d83f1c8ca282 518 if (HAL_SAI_DMAStop(&BSP_AUDIO_hSai_Tx) != HAL_OK)
bcostm 0:d83f1c8ca282 519 {
bcostm 0:d83f1c8ca282 520 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 521 }
bcostm 0:d83f1c8ca282 522
bcostm 0:d83f1c8ca282 523 return AUDIO_OK;
bcostm 0:d83f1c8ca282 524 }
bcostm 0:d83f1c8ca282 525
bcostm 0:d83f1c8ca282 526 /**
bcostm 0:d83f1c8ca282 527 * @brief Controls the current audio volume level.
bcostm 0:d83f1c8ca282 528 * @param Volume: Volume level to be set in percentage from 0% to 100% (0 for
bcostm 0:d83f1c8ca282 529 * Mute and 100 for Max volume level).
bcostm 0:d83f1c8ca282 530 * @retval BSP AUDIO status
bcostm 0:d83f1c8ca282 531 */
bcostm 0:d83f1c8ca282 532 uint8_t BSP_AUDIO_OUT_SetVolume(uint8_t Volume)
bcostm 0:d83f1c8ca282 533 {
bcostm 0:d83f1c8ca282 534 /* Call the codec volume control function with converted volume value */
bcostm 0:d83f1c8ca282 535 if (hAudioOut.AudioDrv->SetVolume(AUDIO_I2C_ADDRESS, Volume) != 0)
bcostm 0:d83f1c8ca282 536 {
bcostm 0:d83f1c8ca282 537 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 538 }
bcostm 0:d83f1c8ca282 539
bcostm 0:d83f1c8ca282 540 hAudioOut.Volume = Volume;
bcostm 0:d83f1c8ca282 541
bcostm 0:d83f1c8ca282 542 return AUDIO_OK;
bcostm 0:d83f1c8ca282 543 }
bcostm 0:d83f1c8ca282 544
bcostm 0:d83f1c8ca282 545 /**
bcostm 0:d83f1c8ca282 546 * @brief Enables or disables the MUTE mode by software
bcostm 0:d83f1c8ca282 547 * @param Cmd: Could be AUDIO_MUTE_ON to mute sound or AUDIO_MUTE_OFF to
bcostm 0:d83f1c8ca282 548 * unmute the codec and restore previous volume level.
bcostm 0:d83f1c8ca282 549 * @retval BSP AUDIO status
bcostm 0:d83f1c8ca282 550 */
bcostm 0:d83f1c8ca282 551 uint8_t BSP_AUDIO_OUT_SetMute(uint32_t Cmd)
bcostm 0:d83f1c8ca282 552 {
bcostm 0:d83f1c8ca282 553 /* Call the Codec Mute function */
bcostm 0:d83f1c8ca282 554 if (hAudioOut.AudioDrv->SetMute(AUDIO_I2C_ADDRESS, Cmd) != 0)
bcostm 0:d83f1c8ca282 555 {
bcostm 0:d83f1c8ca282 556 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 557 }
bcostm 0:d83f1c8ca282 558
bcostm 0:d83f1c8ca282 559 return AUDIO_OK;
bcostm 0:d83f1c8ca282 560 }
bcostm 0:d83f1c8ca282 561
bcostm 0:d83f1c8ca282 562 /**
bcostm 0:d83f1c8ca282 563 * @brief Switch dynamically (while audio file is being played) the output
bcostm 0:d83f1c8ca282 564 * target (speaker or headphone).
bcostm 0:d83f1c8ca282 565 * @param Output: The audio output target: OUTPUT_DEVICE_SPEAKER,
bcostm 0:d83f1c8ca282 566 * OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH
bcostm 0:d83f1c8ca282 567 * @retval BSP AUDIO status
bcostm 0:d83f1c8ca282 568 */
bcostm 0:d83f1c8ca282 569 uint8_t BSP_AUDIO_OUT_SetOutputMode(uint8_t Output)
bcostm 0:d83f1c8ca282 570 {
bcostm 0:d83f1c8ca282 571 /* Call the Codec output device function */
bcostm 0:d83f1c8ca282 572 if (hAudioOut.AudioDrv->SetOutputMode(AUDIO_I2C_ADDRESS, Output) != 0)
bcostm 0:d83f1c8ca282 573 {
bcostm 0:d83f1c8ca282 574 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 575 }
bcostm 0:d83f1c8ca282 576
bcostm 0:d83f1c8ca282 577 return AUDIO_OK;
bcostm 0:d83f1c8ca282 578 }
bcostm 0:d83f1c8ca282 579
bcostm 0:d83f1c8ca282 580 /**
bcostm 0:d83f1c8ca282 581 * @brief Updates the audio frequency.
bcostm 0:d83f1c8ca282 582 * @param AudioFreq: Audio frequency used to play the audio stream.
bcostm 0:d83f1c8ca282 583 * @note The SAI PLL input clock must be configure in the user application.
bcostm 0:d83f1c8ca282 584 * The SAI PLL configuration done within this function assumes that
bcostm 0:d83f1c8ca282 585 * the SAI PLL input clock runs at 8 MHz.
bcostm 0:d83f1c8ca282 586 * @retval BSP AUDIO status
bcostm 0:d83f1c8ca282 587 */
bcostm 0:d83f1c8ca282 588 uint8_t BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq)
bcostm 0:d83f1c8ca282 589 {
bcostm 0:d83f1c8ca282 590 uint8_t TxData[2] = {0x00, 0x00};
bcostm 0:d83f1c8ca282 591
bcostm 0:d83f1c8ca282 592 /* Configure the SAI PLL according to the requested audio frequency */
bcostm 0:d83f1c8ca282 593 if (AUDIO_SAIPLLConfig(AudioFreq) != AUDIO_OK)
bcostm 0:d83f1c8ca282 594 {
bcostm 0:d83f1c8ca282 595 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 596 }
bcostm 0:d83f1c8ca282 597
bcostm 0:d83f1c8ca282 598 /* Disable SAI peripheral to allow access to SAI internal registers */
bcostm 0:d83f1c8ca282 599 __HAL_SAI_DISABLE(&BSP_AUDIO_hSai_Tx);
bcostm 0:d83f1c8ca282 600 __HAL_SAI_DISABLE(&BSP_AUDIO_hSai_Rx);
bcostm 0:d83f1c8ca282 601
bcostm 0:d83f1c8ca282 602 /* Update the SAI audio frequency configuration */
bcostm 0:d83f1c8ca282 603 BSP_AUDIO_hSai_Tx.Init.Mckdiv = SAIClockDivider(AudioFreq);
bcostm 0:d83f1c8ca282 604 HAL_SAI_Init(&BSP_AUDIO_hSai_Tx);
bcostm 0:d83f1c8ca282 605 BSP_AUDIO_hSai_Rx.Init.Mckdiv = SAIClockDivider(AudioFreq);
bcostm 0:d83f1c8ca282 606 HAL_SAI_Init(&BSP_AUDIO_hSai_Rx);
bcostm 0:d83f1c8ca282 607
bcostm 0:d83f1c8ca282 608 /* Enable SAI peripheral to generate MCLK */
bcostm 0:d83f1c8ca282 609 __HAL_SAI_ENABLE(&BSP_AUDIO_hSai_Tx);
bcostm 0:d83f1c8ca282 610 /* Transmit one byte to start FS generation */
bcostm 0:d83f1c8ca282 611 if (HAL_SAI_Transmit(&BSP_AUDIO_hSai_Tx, TxData, 2, 1000) != HAL_OK)
bcostm 0:d83f1c8ca282 612 {
bcostm 0:d83f1c8ca282 613 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 614 }
bcostm 0:d83f1c8ca282 615
bcostm 0:d83f1c8ca282 616 hAudioOut.Frequency = AudioFreq;
bcostm 0:d83f1c8ca282 617
bcostm 0:d83f1c8ca282 618 return AUDIO_OK;
bcostm 0:d83f1c8ca282 619 }
bcostm 0:d83f1c8ca282 620
bcostm 0:d83f1c8ca282 621 /**
bcostm 0:d83f1c8ca282 622 * @brief Changes the Audio Out Configuration.
bcostm 0:d83f1c8ca282 623 * @param AudioOutOption: specifies the audio out new configuration
bcostm 0:d83f1c8ca282 624 * This parameter can be any value of @ref BSP_Audio_Out_Option
bcostm 0:d83f1c8ca282 625 * @note This API should be called after the BSP_AUDIO_OUT_Init() to adjust the
bcostm 0:d83f1c8ca282 626 * audio out configuration.
bcostm 0:d83f1c8ca282 627 * @retval None
bcostm 0:d83f1c8ca282 628 */
bcostm 0:d83f1c8ca282 629 void BSP_AUDIO_OUT_ChangeAudioConfig(uint32_t AudioOutOption)
bcostm 0:d83f1c8ca282 630 {
bcostm 0:d83f1c8ca282 631 uint8_t TxData[2] = {0x00, 0x00};
bcostm 0:d83f1c8ca282 632
bcostm 0:d83f1c8ca282 633 /********** Playback Buffer circular/normal mode **********/
bcostm 0:d83f1c8ca282 634 if (AudioOutOption & BSP_AUDIO_OUT_CIRCULARMODE)
bcostm 0:d83f1c8ca282 635 {
bcostm 0:d83f1c8ca282 636 /* Deinitialize the Stream to update DMA mode */
bcostm 0:d83f1c8ca282 637 HAL_DMA_DeInit(BSP_AUDIO_hSai_Tx.hdmatx);
bcostm 0:d83f1c8ca282 638
bcostm 0:d83f1c8ca282 639 /* Update the SAI audio Transfer DMA mode */
bcostm 0:d83f1c8ca282 640 BSP_AUDIO_hSai_Tx.hdmatx->Init.Mode = DMA_CIRCULAR;
bcostm 0:d83f1c8ca282 641
bcostm 0:d83f1c8ca282 642 /* Configure the DMA Stream with new Transfer DMA mode */
bcostm 0:d83f1c8ca282 643 HAL_DMA_Init(BSP_AUDIO_hSai_Tx.hdmatx);
bcostm 0:d83f1c8ca282 644 }
bcostm 0:d83f1c8ca282 645 else /* BSP_AUDIO_OUT_NORMALMODE */
bcostm 0:d83f1c8ca282 646 {
bcostm 0:d83f1c8ca282 647 /* Deinitialize the Stream to update DMA mode */
bcostm 0:d83f1c8ca282 648 HAL_DMA_DeInit(BSP_AUDIO_hSai_Tx.hdmatx);
bcostm 0:d83f1c8ca282 649
bcostm 0:d83f1c8ca282 650 /* Update the SAI audio Transfer DMA mode */
bcostm 0:d83f1c8ca282 651 BSP_AUDIO_hSai_Tx.hdmatx->Init.Mode = DMA_NORMAL;
bcostm 0:d83f1c8ca282 652
bcostm 0:d83f1c8ca282 653 /* Configure the DMA Stream with new Transfer DMA mode */
bcostm 0:d83f1c8ca282 654 HAL_DMA_Init(BSP_AUDIO_hSai_Tx.hdmatx);
bcostm 0:d83f1c8ca282 655 }
bcostm 0:d83f1c8ca282 656
bcostm 0:d83f1c8ca282 657 /********** Playback Buffer stereo/mono mode **********/
bcostm 0:d83f1c8ca282 658 if (AudioOutOption & BSP_AUDIO_OUT_STEREOMODE)
bcostm 0:d83f1c8ca282 659 {
bcostm 0:d83f1c8ca282 660 /* Disable SAI peripheral to allow access to SAI internal registers */
bcostm 0:d83f1c8ca282 661 __HAL_SAI_DISABLE(&BSP_AUDIO_hSai_Tx);
bcostm 0:d83f1c8ca282 662
bcostm 0:d83f1c8ca282 663 /* Update the SAI audio frame slot configuration */
bcostm 0:d83f1c8ca282 664 BSP_AUDIO_hSai_Tx.Init.MonoStereoMode = SAI_STEREOMODE;
bcostm 0:d83f1c8ca282 665 HAL_SAI_Init(&BSP_AUDIO_hSai_Tx);
bcostm 0:d83f1c8ca282 666
bcostm 0:d83f1c8ca282 667 /* Enable SAI peripheral to generate MCLK */
bcostm 0:d83f1c8ca282 668 __HAL_SAI_ENABLE(&BSP_AUDIO_hSai_Tx);
bcostm 0:d83f1c8ca282 669 /* Transmit one byte to start FS generation */
bcostm 0:d83f1c8ca282 670 HAL_SAI_Transmit(&BSP_AUDIO_hSai_Tx, TxData, 2, 1000);
bcostm 0:d83f1c8ca282 671 }
bcostm 0:d83f1c8ca282 672 else /* BSP_AUDIO_OUT_MONOMODE */
bcostm 0:d83f1c8ca282 673 {
bcostm 0:d83f1c8ca282 674 /* Disable SAI peripheral to allow access to SAI internal registers */
bcostm 0:d83f1c8ca282 675 __HAL_SAI_DISABLE(&BSP_AUDIO_hSai_Tx);
bcostm 0:d83f1c8ca282 676
bcostm 0:d83f1c8ca282 677 /* Update the SAI audio frame slot configuration */
bcostm 0:d83f1c8ca282 678 BSP_AUDIO_hSai_Tx.Init.MonoStereoMode = SAI_MONOMODE;
bcostm 0:d83f1c8ca282 679 HAL_SAI_Init(&BSP_AUDIO_hSai_Tx);
bcostm 0:d83f1c8ca282 680
bcostm 0:d83f1c8ca282 681 /* Enable SAI peripheral to generate MCLK */
bcostm 0:d83f1c8ca282 682 __HAL_SAI_ENABLE(&BSP_AUDIO_hSai_Tx);
bcostm 0:d83f1c8ca282 683 /* Transmit one byte to start FS generation */
bcostm 0:d83f1c8ca282 684 HAL_SAI_Transmit(&BSP_AUDIO_hSai_Tx, TxData, 2, 1000);
bcostm 0:d83f1c8ca282 685 }
bcostm 0:d83f1c8ca282 686 }
bcostm 0:d83f1c8ca282 687
bcostm 0:d83f1c8ca282 688 /**
bcostm 0:d83f1c8ca282 689 * @brief register user callback functions
bcostm 0:d83f1c8ca282 690 * @param ErrorCallback: pointer to the error callback function
bcostm 0:d83f1c8ca282 691 * @param HalfTransferCallback: pointer to the half transfer callback function
bcostm 0:d83f1c8ca282 692 * @param TransferCompleteCallback: pointer to the transfer complete callback function
bcostm 0:d83f1c8ca282 693 * @retval None
bcostm 0:d83f1c8ca282 694 */
bcostm 0:d83f1c8ca282 695 void BSP_AUDIO_OUT_RegisterCallbacks(Audio_CallbackTypeDef ErrorCallback,
bcostm 0:d83f1c8ca282 696 Audio_CallbackTypeDef HalfTransferCallback,
bcostm 0:d83f1c8ca282 697 Audio_CallbackTypeDef TransferCompleteCallback)
bcostm 0:d83f1c8ca282 698 {
bcostm 0:d83f1c8ca282 699 hAudioOut.CbError = ErrorCallback;
bcostm 0:d83f1c8ca282 700 hAudioOut.CbHalfTransfer = HalfTransferCallback;
bcostm 0:d83f1c8ca282 701 hAudioOut.CbTransferComplete = TransferCompleteCallback;
bcostm 0:d83f1c8ca282 702 }
bcostm 0:d83f1c8ca282 703
bcostm 0:d83f1c8ca282 704 /**
bcostm 0:d83f1c8ca282 705 * @brief Tx Transfer completed callbacks.
bcostm 0:d83f1c8ca282 706 * @param hsai: SAI handle
bcostm 0:d83f1c8ca282 707 * @retval None
bcostm 0:d83f1c8ca282 708 */
bcostm 0:d83f1c8ca282 709 void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
bcostm 0:d83f1c8ca282 710 {
bcostm 0:d83f1c8ca282 711 /* Invoke the registered 'TransferComplete' function (if any) */
bcostm 0:d83f1c8ca282 712 if (hAudioOut.CbTransferComplete != (Audio_CallbackTypeDef)NULL)
bcostm 0:d83f1c8ca282 713 {
bcostm 0:d83f1c8ca282 714 hAudioOut.CbTransferComplete();
bcostm 0:d83f1c8ca282 715 }
bcostm 0:d83f1c8ca282 716 }
bcostm 0:d83f1c8ca282 717
bcostm 0:d83f1c8ca282 718 /**
bcostm 0:d83f1c8ca282 719 * @brief Tx Half Transfer completed callbacks.
bcostm 0:d83f1c8ca282 720 * @param hsai: SAI handle
bcostm 0:d83f1c8ca282 721 * @retval None
bcostm 0:d83f1c8ca282 722 */
bcostm 0:d83f1c8ca282 723 void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
bcostm 0:d83f1c8ca282 724 {
bcostm 0:d83f1c8ca282 725 /* Invoke the registered 'HalfTransfer' callback function (if any) */
bcostm 0:d83f1c8ca282 726 if (hAudioOut.CbHalfTransfer != (Audio_CallbackTypeDef)NULL)
bcostm 0:d83f1c8ca282 727 {
bcostm 0:d83f1c8ca282 728 hAudioOut.CbHalfTransfer();
bcostm 0:d83f1c8ca282 729 }
bcostm 0:d83f1c8ca282 730 }
bcostm 0:d83f1c8ca282 731
bcostm 0:d83f1c8ca282 732 /**
bcostm 0:d83f1c8ca282 733 * @brief SAI error callbacks.
bcostm 0:d83f1c8ca282 734 * @param hsai: SAI handle
bcostm 0:d83f1c8ca282 735 * @retval None
bcostm 0:d83f1c8ca282 736 */
bcostm 0:d83f1c8ca282 737 void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai)
bcostm 0:d83f1c8ca282 738 {
bcostm 0:d83f1c8ca282 739 /* Invoke the registered 'ErrorCallback' callback function (if any) */
bcostm 0:d83f1c8ca282 740 if (hAudioOut.CbError != (Audio_CallbackTypeDef)NULL)
bcostm 0:d83f1c8ca282 741 {
bcostm 0:d83f1c8ca282 742 hAudioOut.CbError();
bcostm 0:d83f1c8ca282 743 }
bcostm 0:d83f1c8ca282 744 /* Invoke the registered 'ErrorCallback' callback function (if any) */
bcostm 0:d83f1c8ca282 745 if (hAudioIn.CbError != (Audio_CallbackTypeDef)NULL)
bcostm 0:d83f1c8ca282 746 {
bcostm 0:d83f1c8ca282 747 hAudioIn.CbError();
bcostm 0:d83f1c8ca282 748 }
bcostm 0:d83f1c8ca282 749 }
bcostm 0:d83f1c8ca282 750
bcostm 0:d83f1c8ca282 751 /**
bcostm 0:d83f1c8ca282 752 * @}
bcostm 0:d83f1c8ca282 753 */
bcostm 0:d83f1c8ca282 754
bcostm 0:d83f1c8ca282 755 /** @addtogroup STM32L496G_EVAL_AUDIO_Exported_Functions
bcostm 0:d83f1c8ca282 756 * @{
bcostm 0:d83f1c8ca282 757 */
bcostm 0:d83f1c8ca282 758
bcostm 0:d83f1c8ca282 759 /**
bcostm 0:d83f1c8ca282 760 * @brief Initializes micropone related peripherals.
bcostm 0:d83f1c8ca282 761 * @note This function assumes that the SAI input clock (through PLL_M)
bcostm 0:d83f1c8ca282 762 * is already configured and ready to be used.
bcostm 0:d83f1c8ca282 763 * @param AudioFreq: Audio frequency to be configured for the SAI peripheral.
bcostm 0:d83f1c8ca282 764 * @param BitRes: Audio frequency to be configured for the SAI peripheral.
bcostm 0:d83f1c8ca282 765 * @param ChnlNbr: Audio frequency to be configured for the SAI peripheral.
bcostm 0:d83f1c8ca282 766 * @retval BSP AUDIO status
bcostm 0:d83f1c8ca282 767 */
bcostm 0:d83f1c8ca282 768 uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
bcostm 0:d83f1c8ca282 769 {
bcostm 0:d83f1c8ca282 770 return BSP_AUDIO_IN_InitEx(INPUT_DEVICE_DIGITAL_MIC, AudioFreq, BitRes, ChnlNbr);
bcostm 0:d83f1c8ca282 771 }
bcostm 0:d83f1c8ca282 772
bcostm 0:d83f1c8ca282 773 /**
bcostm 0:d83f1c8ca282 774 * @brief Initialize wave recording.
bcostm 0:d83f1c8ca282 775 * @param InputDevice: INPUT_DEVICE_DIGITAL_MIC, INPUT_DEVICE_DIGITAL_MIC1,
bcostm 0:d83f1c8ca282 776 * INPUT_DEVICE_DIGITAL_MIC2 or INPUT_DEVICE_ANALOG_MIC.
bcostm 0:d83f1c8ca282 777 * @param AudioFreq: Audio frequency to be configured.
bcostm 0:d83f1c8ca282 778 * @param BitRes: Audio bit resolution to be configured..
bcostm 0:d83f1c8ca282 779 * @param ChnlNbr: Number of channel to be configured.
bcostm 0:d83f1c8ca282 780 * @retval AUDIO_OK if correct communication, else wrong communication
bcostm 0:d83f1c8ca282 781 */
bcostm 0:d83f1c8ca282 782 uint8_t BSP_AUDIO_IN_InitEx(uint16_t InputDevice, uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
bcostm 0:d83f1c8ca282 783 {
bcostm 0:d83f1c8ca282 784 /* Update the audio input context */
bcostm 0:d83f1c8ca282 785 hAudioIn.AudioDrv = &cs42l51_drv;
bcostm 0:d83f1c8ca282 786 hAudioIn.InputDevice = InputDevice;
bcostm 0:d83f1c8ca282 787 hAudioIn.Frequency = AudioFreq;
bcostm 0:d83f1c8ca282 788 hAudioIn.BitResolution = BitRes;
bcostm 0:d83f1c8ca282 789 hAudioIn.ChannelNbr = ChnlNbr;
bcostm 0:d83f1c8ca282 790 hAudioIn.CbError = (Audio_CallbackTypeDef)NULL;
bcostm 0:d83f1c8ca282 791 hAudioIn.CbHalfTransfer = (Audio_CallbackTypeDef)NULL;
bcostm 0:d83f1c8ca282 792 hAudioIn.CbTransferComplete = (Audio_CallbackTypeDef)NULL;
bcostm 0:d83f1c8ca282 793
bcostm 0:d83f1c8ca282 794 /* Check channel number according device : only record mono with analog mic and stereo with digital mic are allowed */
bcostm 0:d83f1c8ca282 795 if (((InputDevice == INPUT_DEVICE_DIGITAL_MIC) && (ChnlNbr == 1)) ||
bcostm 0:d83f1c8ca282 796 ((InputDevice == INPUT_DEVICE_DIGITAL_MIC1) && (ChnlNbr == 2)) ||
bcostm 0:d83f1c8ca282 797 ((InputDevice == INPUT_DEVICE_DIGITAL_MIC2) && (ChnlNbr == 2)) ||
bcostm 0:d83f1c8ca282 798 ((InputDevice == INPUT_DEVICE_ANALOG_MIC) && (ChnlNbr == 2)))
bcostm 0:d83f1c8ca282 799 {
bcostm 0:d83f1c8ca282 800 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 801 }
bcostm 0:d83f1c8ca282 802
bcostm 0:d83f1c8ca282 803 /* Check if output device is currently used */
bcostm 0:d83f1c8ca282 804 if (hAudioOut.OutputDevice != 0)
bcostm 0:d83f1c8ca282 805 {
bcostm 0:d83f1c8ca282 806 /* If output device is currently used, SAI PLL is already initialized */
bcostm 0:d83f1c8ca282 807 /* Check that AudioFreq for record and playback is the same */
bcostm 0:d83f1c8ca282 808 if (hAudioIn.Frequency != hAudioOut.Frequency)
bcostm 0:d83f1c8ca282 809 {
bcostm 0:d83f1c8ca282 810 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 811 }
bcostm 0:d83f1c8ca282 812 }
bcostm 0:d83f1c8ca282 813 else
bcostm 0:d83f1c8ca282 814 {
bcostm 0:d83f1c8ca282 815 /* Configure the SAI PLL according to the requested audio frequency */
bcostm 0:d83f1c8ca282 816 if (AUDIO_SAIPLLConfig(AudioFreq) != AUDIO_OK)
bcostm 0:d83f1c8ca282 817 {
bcostm 0:d83f1c8ca282 818 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 819 }
bcostm 0:d83f1c8ca282 820 }
bcostm 0:d83f1c8ca282 821
bcostm 0:d83f1c8ca282 822 if (InputDevice != INPUT_DEVICE_ANALOG_MIC)
bcostm 0:d83f1c8ca282 823 {
bcostm 0:d83f1c8ca282 824 /* Initializes the Digital Filter for Sigma-Delta Modulators interface */
bcostm 0:d83f1c8ca282 825 if (AUDIO_DFSDMx_Init(AudioFreq) != AUDIO_OK)
bcostm 0:d83f1c8ca282 826 {
bcostm 0:d83f1c8ca282 827 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 828 }
bcostm 0:d83f1c8ca282 829 }
bcostm 0:d83f1c8ca282 830 else
bcostm 0:d83f1c8ca282 831 {
bcostm 0:d83f1c8ca282 832 /* INPUT_DEVICE_ANALOG_MIC */
bcostm 0:d83f1c8ca282 833 /* If output device is currently used, SAI is already initialized */
bcostm 0:d83f1c8ca282 834 if (hAudioOut.OutputDevice == 0)
bcostm 0:d83f1c8ca282 835 {
bcostm 0:d83f1c8ca282 836 /* SAI data transfer preparation: prepare the Media to be used for the audio
bcostm 0:d83f1c8ca282 837 transfer from SAI peripheral to memory. */
bcostm 0:d83f1c8ca282 838 if (AUDIO_SAIx_Init(AudioFreq) != AUDIO_OK)
bcostm 0:d83f1c8ca282 839 {
bcostm 0:d83f1c8ca282 840 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 841 }
bcostm 0:d83f1c8ca282 842 }
bcostm 0:d83f1c8ca282 843
bcostm 0:d83f1c8ca282 844 /* Initialize the audio codec internal registers */
bcostm 0:d83f1c8ca282 845 if (hAudioIn.AudioDrv->Init(AUDIO_I2C_ADDRESS,
bcostm 0:d83f1c8ca282 846 (hAudioOut.OutputDevice | hAudioIn.InputDevice),
bcostm 0:d83f1c8ca282 847 hAudioOut.Volume,
bcostm 0:d83f1c8ca282 848 AudioFreq) != 0)
bcostm 0:d83f1c8ca282 849 {
bcostm 0:d83f1c8ca282 850 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 851 }
bcostm 0:d83f1c8ca282 852 }
bcostm 0:d83f1c8ca282 853
bcostm 0:d83f1c8ca282 854 /* Initialise transfer control flag */
bcostm 0:d83f1c8ca282 855 DmaLeftRecHalfBuffCplt = 0;
bcostm 0:d83f1c8ca282 856 DmaLeftRecBuffCplt = 0;
bcostm 0:d83f1c8ca282 857 DmaRightRecHalfBuffCplt = 0;
bcostm 0:d83f1c8ca282 858 DmaRightRecBuffCplt = 0;
bcostm 0:d83f1c8ca282 859
bcostm 0:d83f1c8ca282 860 return AUDIO_OK;
bcostm 0:d83f1c8ca282 861 }
bcostm 0:d83f1c8ca282 862
bcostm 0:d83f1c8ca282 863 /**
bcostm 0:d83f1c8ca282 864 * @brief De-Initializes microphone related peripherals.
bcostm 0:d83f1c8ca282 865 * @retval BSP AUDIO status
bcostm 0:d83f1c8ca282 866
bcostm 0:d83f1c8ca282 867 */
bcostm 0:d83f1c8ca282 868 uint8_t BSP_AUDIO_IN_DeInit(void)
bcostm 0:d83f1c8ca282 869 {
bcostm 0:d83f1c8ca282 870 if (hAudioIn.InputDevice != INPUT_DEVICE_ANALOG_MIC)
bcostm 0:d83f1c8ca282 871 {
bcostm 0:d83f1c8ca282 872 /* De-initializes the Digital Filter for Sigma-Delta Modulators interface */
bcostm 0:d83f1c8ca282 873 if (AUDIO_DFSDMx_DeInit() != AUDIO_OK)
bcostm 0:d83f1c8ca282 874 {
bcostm 0:d83f1c8ca282 875 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 876 }
bcostm 0:d83f1c8ca282 877 }
bcostm 0:d83f1c8ca282 878 else
bcostm 0:d83f1c8ca282 879 {
bcostm 0:d83f1c8ca282 880 /* INPUT_DEVICE_ANALOG_MIC */
bcostm 0:d83f1c8ca282 881 /* Check if output device is currently used */
bcostm 0:d83f1c8ca282 882 if (hAudioOut.OutputDevice != 0)
bcostm 0:d83f1c8ca282 883 {
bcostm 0:d83f1c8ca282 884 /* Reset record path on audio codec */
bcostm 0:d83f1c8ca282 885 if (hAudioOut.AudioDrv->Init(AUDIO_I2C_ADDRESS,
bcostm 0:d83f1c8ca282 886 hAudioOut.OutputDevice,
bcostm 0:d83f1c8ca282 887 (uint8_t) hAudioOut.Volume,
bcostm 0:d83f1c8ca282 888 hAudioOut.Frequency) != 0)
bcostm 0:d83f1c8ca282 889 {
bcostm 0:d83f1c8ca282 890 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 891 }
bcostm 0:d83f1c8ca282 892 }
bcostm 0:d83f1c8ca282 893 else
bcostm 0:d83f1c8ca282 894 {
bcostm 0:d83f1c8ca282 895 /* De-initializes SAI interface */
bcostm 0:d83f1c8ca282 896 if (AUDIO_SAIx_DeInit() != AUDIO_OK)
bcostm 0:d83f1c8ca282 897 {
bcostm 0:d83f1c8ca282 898 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 899 }
bcostm 0:d83f1c8ca282 900
bcostm 0:d83f1c8ca282 901 /* DeInit audio codec */
bcostm 0:d83f1c8ca282 902 hAudioIn.AudioDrv->DeInit();
bcostm 0:d83f1c8ca282 903 }
bcostm 0:d83f1c8ca282 904 }
bcostm 0:d83f1c8ca282 905
bcostm 0:d83f1c8ca282 906 /* Disable SAI PLL if no more device is used */
bcostm 0:d83f1c8ca282 907 if (hAudioOut.OutputDevice == 0)
bcostm 0:d83f1c8ca282 908 {
bcostm 0:d83f1c8ca282 909 if (AUDIO_SAIx_PLL_DISABLE() != AUDIO_OK)
bcostm 0:d83f1c8ca282 910 {
bcostm 0:d83f1c8ca282 911 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 912 }
bcostm 0:d83f1c8ca282 913 }
bcostm 0:d83f1c8ca282 914
bcostm 0:d83f1c8ca282 915 /* Reset the audio input context */
bcostm 0:d83f1c8ca282 916 memset(&hAudioIn, 0, sizeof(hAudioIn));
bcostm 0:d83f1c8ca282 917
bcostm 0:d83f1c8ca282 918 return AUDIO_OK;
bcostm 0:d83f1c8ca282 919 }
bcostm 0:d83f1c8ca282 920
bcostm 0:d83f1c8ca282 921 /**
bcostm 0:d83f1c8ca282 922 * @brief Starts audio recording.
bcostm 0:d83f1c8ca282 923 * @param pbuf: Main buffer pointer for the recorded data storing
bcostm 0:d83f1c8ca282 924 * @param size: Current size of the recorded buffer
bcostm 0:d83f1c8ca282 925 * @note The Right channel is start at first with synchro on start of Left channel
bcostm 0:d83f1c8ca282 926 * @retval BSP AUDIO status
bcostm 0:d83f1c8ca282 927 */
bcostm 0:d83f1c8ca282 928 uint8_t BSP_AUDIO_IN_Record(uint16_t *pbuf, uint32_t size)
bcostm 0:d83f1c8ca282 929 {
bcostm 0:d83f1c8ca282 930 hAudioIn.pRecBuf = pbuf;
bcostm 0:d83f1c8ca282 931 hAudioIn.RecSize = size;
bcostm 0:d83f1c8ca282 932
bcostm 0:d83f1c8ca282 933
bcostm 0:d83f1c8ca282 934 if (hAudioIn.InputDevice != INPUT_DEVICE_ANALOG_MIC)
bcostm 0:d83f1c8ca282 935 {
bcostm 0:d83f1c8ca282 936 if ((hAudioIn.InputDevice & INPUT_DEVICE_DIGITAL_MIC1) == INPUT_DEVICE_DIGITAL_MIC1)
bcostm 0:d83f1c8ca282 937 {
bcostm 0:d83f1c8ca282 938 /* Allocate hAudioIn.LeftRecBuff buffer */
bcostm 0:d83f1c8ca282 939 #if defined(BSP_AUDIO_USE_RTOS)
bcostm 0:d83f1c8ca282 940 hAudioIn.LeftRecBuff = (int32_t *)k_malloc((size / hAudioIn.ChannelNbr) * sizeof(int32_t));
bcostm 0:d83f1c8ca282 941 #else
bcostm 0:d83f1c8ca282 942 hAudioIn.LeftRecBuff = (int32_t *)malloc((size / hAudioIn.ChannelNbr) * sizeof(int32_t));
bcostm 0:d83f1c8ca282 943 #endif
bcostm 0:d83f1c8ca282 944 if (hAudioIn.LeftRecBuff == NULL)
bcostm 0:d83f1c8ca282 945 {
bcostm 0:d83f1c8ca282 946 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 947 }
bcostm 0:d83f1c8ca282 948 }
bcostm 0:d83f1c8ca282 949
bcostm 0:d83f1c8ca282 950 if ((hAudioIn.InputDevice & INPUT_DEVICE_DIGITAL_MIC2) == INPUT_DEVICE_DIGITAL_MIC2)
bcostm 0:d83f1c8ca282 951 {
bcostm 0:d83f1c8ca282 952 /* Allocate hAudioIn.RightRecBuff buffer */
bcostm 0:d83f1c8ca282 953 #if defined(BSP_AUDIO_USE_RTOS)
bcostm 0:d83f1c8ca282 954 hAudioIn.RightRecBuff = (int32_t *)k_malloc((size / hAudioIn.ChannelNbr) * sizeof(int32_t));
bcostm 0:d83f1c8ca282 955 #else
bcostm 0:d83f1c8ca282 956 hAudioIn.RightRecBuff = (int32_t *)malloc((size / hAudioIn.ChannelNbr) * sizeof(int32_t));
bcostm 0:d83f1c8ca282 957 #endif
bcostm 0:d83f1c8ca282 958 if (hAudioIn.RightRecBuff == NULL)
bcostm 0:d83f1c8ca282 959 {
bcostm 0:d83f1c8ca282 960 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 961 }
bcostm 0:d83f1c8ca282 962 }
bcostm 0:d83f1c8ca282 963
bcostm 0:d83f1c8ca282 964 if ((hAudioIn.InputDevice & INPUT_DEVICE_DIGITAL_MIC2) == INPUT_DEVICE_DIGITAL_MIC2)
bcostm 0:d83f1c8ca282 965 {
bcostm 0:d83f1c8ca282 966 /* Call the Media layer start function for right channel */
bcostm 0:d83f1c8ca282 967 if (HAL_DFSDM_FilterRegularStart_DMA(&BSP_AUDIO_hDfsdmRightFilter,
bcostm 0:d83f1c8ca282 968 (int32_t *)hAudioIn.RightRecBuff,
bcostm 0:d83f1c8ca282 969 (hAudioIn.RecSize / hAudioIn.ChannelNbr)) != HAL_OK)
bcostm 0:d83f1c8ca282 970 {
bcostm 0:d83f1c8ca282 971 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 972 }
bcostm 0:d83f1c8ca282 973 }
bcostm 0:d83f1c8ca282 974
bcostm 0:d83f1c8ca282 975 if ((hAudioIn.InputDevice & INPUT_DEVICE_DIGITAL_MIC1) == INPUT_DEVICE_DIGITAL_MIC1)
bcostm 0:d83f1c8ca282 976 {
bcostm 0:d83f1c8ca282 977 /* Call the Media layer start function for left channel */
bcostm 0:d83f1c8ca282 978 if (HAL_DFSDM_FilterRegularStart_DMA(&BSP_AUDIO_hDfsdmLeftFilter,
bcostm 0:d83f1c8ca282 979 (int32_t *)hAudioIn.LeftRecBuff,
bcostm 0:d83f1c8ca282 980 (hAudioIn.RecSize / hAudioIn.ChannelNbr)) != HAL_OK)
bcostm 0:d83f1c8ca282 981 {
bcostm 0:d83f1c8ca282 982 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 983 }
bcostm 0:d83f1c8ca282 984 }
bcostm 0:d83f1c8ca282 985 }
bcostm 0:d83f1c8ca282 986 else
bcostm 0:d83f1c8ca282 987 {
bcostm 0:d83f1c8ca282 988 /* INPUT_DEVICE_ANALOG_MIC */
bcostm 0:d83f1c8ca282 989 /* Call the audio Codec Play function */
bcostm 0:d83f1c8ca282 990 if (hAudioIn.AudioDrv->Play(AUDIO_I2C_ADDRESS, pbuf, size) != 0)
bcostm 0:d83f1c8ca282 991 {
bcostm 0:d83f1c8ca282 992 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 993 }
bcostm 0:d83f1c8ca282 994
bcostm 0:d83f1c8ca282 995 /* Start the process receive DMA */
bcostm 0:d83f1c8ca282 996 if (HAL_OK != HAL_SAI_Receive_DMA(&BSP_AUDIO_hSai_Rx, (uint8_t *)pbuf, size))
bcostm 0:d83f1c8ca282 997 {
bcostm 0:d83f1c8ca282 998 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 999 }
bcostm 0:d83f1c8ca282 1000 }
bcostm 0:d83f1c8ca282 1001
bcostm 0:d83f1c8ca282 1002 return AUDIO_OK;
bcostm 0:d83f1c8ca282 1003 }
bcostm 0:d83f1c8ca282 1004
bcostm 0:d83f1c8ca282 1005 /**
bcostm 0:d83f1c8ca282 1006 * @brief Updates the audio frequency.
bcostm 0:d83f1c8ca282 1007 * @param AudioFreq: Audio frequency used to record the audio stream.
bcostm 0:d83f1c8ca282 1008 * @note This API should be called after the BSP_AUDIO_IN_Init() to adjust the
bcostm 0:d83f1c8ca282 1009 * audio frequency.
bcostm 0:d83f1c8ca282 1010 * @retval BSP AUDIO status
bcostm 0:d83f1c8ca282 1011 */
bcostm 0:d83f1c8ca282 1012 uint8_t BSP_AUDIO_IN_SetFrequency(uint32_t AudioFreq)
bcostm 0:d83f1c8ca282 1013 {
bcostm 0:d83f1c8ca282 1014 uint8_t TxData[2] = {0x00, 0x00};
bcostm 0:d83f1c8ca282 1015
bcostm 0:d83f1c8ca282 1016 /* Configure the SAI PLL according to the requested audio frequency */
bcostm 0:d83f1c8ca282 1017 if (AUDIO_SAIPLLConfig(AudioFreq) != AUDIO_OK)
bcostm 0:d83f1c8ca282 1018 {
bcostm 0:d83f1c8ca282 1019 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1020 }
bcostm 0:d83f1c8ca282 1021
bcostm 0:d83f1c8ca282 1022 if (hAudioIn.InputDevice != INPUT_DEVICE_ANALOG_MIC)
bcostm 0:d83f1c8ca282 1023 {
bcostm 0:d83f1c8ca282 1024 /* De-initializes the Digital Filter for Sigma-Delta Modulators interface */
bcostm 0:d83f1c8ca282 1025 if (AUDIO_DFSDMx_DeInit() != AUDIO_OK)
bcostm 0:d83f1c8ca282 1026 {
bcostm 0:d83f1c8ca282 1027 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1028 }
bcostm 0:d83f1c8ca282 1029
bcostm 0:d83f1c8ca282 1030 /* Initializes the Digital Filter for Sigma-Delta Modulators interface */
bcostm 0:d83f1c8ca282 1031 if (AUDIO_DFSDMx_Init(AudioFreq) != AUDIO_OK)
bcostm 0:d83f1c8ca282 1032 {
bcostm 0:d83f1c8ca282 1033 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1034 }
bcostm 0:d83f1c8ca282 1035 }
bcostm 0:d83f1c8ca282 1036 else
bcostm 0:d83f1c8ca282 1037 {
bcostm 0:d83f1c8ca282 1038 /* INPUT_DEVICE_ANALOG_MIC */
bcostm 0:d83f1c8ca282 1039 /* Disable SAI peripheral to allow access to SAI internal registers */
bcostm 0:d83f1c8ca282 1040 __HAL_SAI_DISABLE(&BSP_AUDIO_hSai_Tx);
bcostm 0:d83f1c8ca282 1041 __HAL_SAI_DISABLE(&BSP_AUDIO_hSai_Rx);
bcostm 0:d83f1c8ca282 1042
bcostm 0:d83f1c8ca282 1043 /* Update the SAI audio frequency configuration */
bcostm 0:d83f1c8ca282 1044 BSP_AUDIO_hSai_Tx.Init.Mckdiv = SAIClockDivider(AudioFreq);
bcostm 0:d83f1c8ca282 1045 HAL_SAI_Init(&BSP_AUDIO_hSai_Tx);
bcostm 0:d83f1c8ca282 1046 BSP_AUDIO_hSai_Rx.Init.Mckdiv = SAIClockDivider(AudioFreq);
bcostm 0:d83f1c8ca282 1047 HAL_SAI_Init(&BSP_AUDIO_hSai_Rx);
bcostm 0:d83f1c8ca282 1048
bcostm 0:d83f1c8ca282 1049 /* Enable SAI peripheral to generate MCLK */
bcostm 0:d83f1c8ca282 1050 __HAL_SAI_ENABLE(&BSP_AUDIO_hSai_Tx);
bcostm 0:d83f1c8ca282 1051 /* Transmit one byte to start FS generation */
bcostm 0:d83f1c8ca282 1052 if (HAL_SAI_Transmit(&BSP_AUDIO_hSai_Tx, TxData, 2, 1000) != HAL_OK)
bcostm 0:d83f1c8ca282 1053 {
bcostm 0:d83f1c8ca282 1054 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1055 }
bcostm 0:d83f1c8ca282 1056 }
bcostm 0:d83f1c8ca282 1057
bcostm 0:d83f1c8ca282 1058 hAudioIn.Frequency = AudioFreq;
bcostm 0:d83f1c8ca282 1059
bcostm 0:d83f1c8ca282 1060 return AUDIO_OK;
bcostm 0:d83f1c8ca282 1061 }
bcostm 0:d83f1c8ca282 1062
bcostm 0:d83f1c8ca282 1063 /**
bcostm 0:d83f1c8ca282 1064 * @brief Regular conversion complete callback.
bcostm 0:d83f1c8ca282 1065 * @note In interrupt mode, user has to read conversion value in this function
bcostm 0:d83f1c8ca282 1066 using HAL_DFSDM_FilterGetRegularValue.
bcostm 0:d83f1c8ca282 1067 * @param hdfsdm_filter : DFSDM filter handle.
bcostm 0:d83f1c8ca282 1068 * @retval None
bcostm 0:d83f1c8ca282 1069 */
bcostm 0:d83f1c8ca282 1070 void HAL_DFSDM_FilterRegConvCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
bcostm 0:d83f1c8ca282 1071 {
bcostm 0:d83f1c8ca282 1072 uint32_t index;
bcostm 0:d83f1c8ca282 1073 uint32_t recbufsize = (hAudioIn.RecSize / hAudioIn.ChannelNbr);
bcostm 0:d83f1c8ca282 1074
bcostm 0:d83f1c8ca282 1075 if (hAudioIn.InputDevice == INPUT_DEVICE_DIGITAL_MIC)
bcostm 0:d83f1c8ca282 1076 {
bcostm 0:d83f1c8ca282 1077 for (index = (recbufsize / 2); index < recbufsize; index++)
bcostm 0:d83f1c8ca282 1078 {
bcostm 0:d83f1c8ca282 1079 hAudioIn.pRecBuf[2 * index] = (uint16_t)(SaturaLH((hAudioIn.LeftRecBuff[index] >> 8), -32768, 32767));
bcostm 0:d83f1c8ca282 1080 hAudioIn.pRecBuf[(2 * index) + 1] = (uint16_t)(SaturaLH((hAudioIn.RightRecBuff[index] >> 8), -32768, 32767));
bcostm 0:d83f1c8ca282 1081 }
bcostm 0:d83f1c8ca282 1082 }
bcostm 0:d83f1c8ca282 1083 else if (hAudioIn.InputDevice == INPUT_DEVICE_DIGITAL_MIC1)
bcostm 0:d83f1c8ca282 1084 {
bcostm 0:d83f1c8ca282 1085 for (index = (recbufsize / 2); index < recbufsize; index++)
bcostm 0:d83f1c8ca282 1086 {
bcostm 0:d83f1c8ca282 1087 hAudioIn.pRecBuf[index] = (uint16_t)(SaturaLH((hAudioIn.LeftRecBuff[index] >> 8), -32768, 32767));
bcostm 0:d83f1c8ca282 1088 }
bcostm 0:d83f1c8ca282 1089 }
bcostm 0:d83f1c8ca282 1090 else if (hAudioIn.InputDevice == INPUT_DEVICE_DIGITAL_MIC2)
bcostm 0:d83f1c8ca282 1091 {
bcostm 0:d83f1c8ca282 1092 for (index = (recbufsize / 2); index < recbufsize; index++)
bcostm 0:d83f1c8ca282 1093 {
bcostm 0:d83f1c8ca282 1094 hAudioIn.pRecBuf[index] = (uint16_t)(SaturaLH((hAudioIn.RightRecBuff[index] >> 8), -32768, 32767));
bcostm 0:d83f1c8ca282 1095 }
bcostm 0:d83f1c8ca282 1096 }
bcostm 0:d83f1c8ca282 1097
bcostm 0:d83f1c8ca282 1098 /* Invoke the registered 'TransferCompete' callback function (if any) */
bcostm 0:d83f1c8ca282 1099 if (hAudioIn.CbTransferComplete != (Audio_CallbackTypeDef)NULL)
bcostm 0:d83f1c8ca282 1100 {
bcostm 0:d83f1c8ca282 1101 if (hdfsdm_filter == &BSP_AUDIO_hDfsdmLeftFilter)
bcostm 0:d83f1c8ca282 1102 {
bcostm 0:d83f1c8ca282 1103 if (DmaLeftRecBuffCplt)
bcostm 0:d83f1c8ca282 1104 {
bcostm 0:d83f1c8ca282 1105 BSP_ErrorHandler();
bcostm 0:d83f1c8ca282 1106 }
bcostm 0:d83f1c8ca282 1107
bcostm 0:d83f1c8ca282 1108 DmaLeftRecBuffCplt = 1;
bcostm 0:d83f1c8ca282 1109 }
bcostm 0:d83f1c8ca282 1110 else
bcostm 0:d83f1c8ca282 1111 {
bcostm 0:d83f1c8ca282 1112 if (DmaRightRecBuffCplt)
bcostm 0:d83f1c8ca282 1113 {
bcostm 0:d83f1c8ca282 1114 BSP_ErrorHandler();
bcostm 0:d83f1c8ca282 1115 }
bcostm 0:d83f1c8ca282 1116
bcostm 0:d83f1c8ca282 1117 DmaRightRecBuffCplt = 1;
bcostm 0:d83f1c8ca282 1118 }
bcostm 0:d83f1c8ca282 1119
bcostm 0:d83f1c8ca282 1120 if (((DmaLeftRecBuffCplt != 0) && (DmaRightRecBuffCplt != 0) && (hAudioIn.InputDevice == INPUT_DEVICE_DIGITAL_MIC)) ||
bcostm 0:d83f1c8ca282 1121 ((DmaLeftRecBuffCplt != 0) && (hAudioIn.InputDevice == INPUT_DEVICE_DIGITAL_MIC1)) ||
bcostm 0:d83f1c8ca282 1122 ((DmaRightRecBuffCplt != 0) && (hAudioIn.InputDevice == INPUT_DEVICE_DIGITAL_MIC2)))
bcostm 0:d83f1c8ca282 1123 {
bcostm 0:d83f1c8ca282 1124 hAudioIn.CbTransferComplete();
bcostm 0:d83f1c8ca282 1125 DmaLeftRecBuffCplt = 0;
bcostm 0:d83f1c8ca282 1126 DmaRightRecBuffCplt = 0;
bcostm 0:d83f1c8ca282 1127 }
bcostm 0:d83f1c8ca282 1128 }
bcostm 0:d83f1c8ca282 1129 }
bcostm 0:d83f1c8ca282 1130
bcostm 0:d83f1c8ca282 1131 /**
bcostm 0:d83f1c8ca282 1132 * @brief Half regular conversion complete callback.
bcostm 0:d83f1c8ca282 1133 * @param hdfsdm_filter : DFSDM filter handle.
bcostm 0:d83f1c8ca282 1134 * @retval None
bcostm 0:d83f1c8ca282 1135 */
bcostm 0:d83f1c8ca282 1136 void HAL_DFSDM_FilterRegConvHalfCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
bcostm 0:d83f1c8ca282 1137 {
bcostm 0:d83f1c8ca282 1138 uint32_t index;
bcostm 0:d83f1c8ca282 1139 uint32_t recbufsize = (hAudioIn.RecSize / hAudioIn.ChannelNbr);
bcostm 0:d83f1c8ca282 1140
bcostm 0:d83f1c8ca282 1141 if (hAudioIn.InputDevice == INPUT_DEVICE_DIGITAL_MIC)
bcostm 0:d83f1c8ca282 1142 {
bcostm 0:d83f1c8ca282 1143 for (index = 0; index < (recbufsize / 2); index++)
bcostm 0:d83f1c8ca282 1144 {
bcostm 0:d83f1c8ca282 1145 hAudioIn.pRecBuf[2 * index] = (uint16_t)(SaturaLH((hAudioIn.LeftRecBuff[index] >> 8), -32768, 32767));
bcostm 0:d83f1c8ca282 1146 hAudioIn.pRecBuf[(2 * index) + 1] = (uint16_t)(SaturaLH((hAudioIn.RightRecBuff[index] >> 8), -32768, 32767));
bcostm 0:d83f1c8ca282 1147 }
bcostm 0:d83f1c8ca282 1148 }
bcostm 0:d83f1c8ca282 1149 else if (hAudioIn.InputDevice == INPUT_DEVICE_DIGITAL_MIC1)
bcostm 0:d83f1c8ca282 1150 {
bcostm 0:d83f1c8ca282 1151 for (index = 0; index < (recbufsize / 2); index++)
bcostm 0:d83f1c8ca282 1152 {
bcostm 0:d83f1c8ca282 1153 hAudioIn.pRecBuf[index] = (uint16_t)(SaturaLH((hAudioIn.LeftRecBuff[index] >> 8), -32768, 32767));
bcostm 0:d83f1c8ca282 1154 }
bcostm 0:d83f1c8ca282 1155 }
bcostm 0:d83f1c8ca282 1156 else if (hAudioIn.InputDevice == INPUT_DEVICE_DIGITAL_MIC2)
bcostm 0:d83f1c8ca282 1157 {
bcostm 0:d83f1c8ca282 1158 for (index = 0; index < (recbufsize / 2); index++)
bcostm 0:d83f1c8ca282 1159 {
bcostm 0:d83f1c8ca282 1160 hAudioIn.pRecBuf[index] = (uint16_t)(SaturaLH((hAudioIn.RightRecBuff[index] >> 8), -32768, 32767));
bcostm 0:d83f1c8ca282 1161 }
bcostm 0:d83f1c8ca282 1162 }
bcostm 0:d83f1c8ca282 1163
bcostm 0:d83f1c8ca282 1164 /* Invoke the registered 'HalfTransfer' callback function (if any) */
bcostm 0:d83f1c8ca282 1165 if (hAudioIn.CbHalfTransfer != (Audio_CallbackTypeDef)NULL)
bcostm 0:d83f1c8ca282 1166 {
bcostm 0:d83f1c8ca282 1167 if (hdfsdm_filter == &BSP_AUDIO_hDfsdmLeftFilter)
bcostm 0:d83f1c8ca282 1168 {
bcostm 0:d83f1c8ca282 1169 if (DmaLeftRecHalfBuffCplt)
bcostm 0:d83f1c8ca282 1170 {
bcostm 0:d83f1c8ca282 1171 BSP_ErrorHandler();
bcostm 0:d83f1c8ca282 1172 }
bcostm 0:d83f1c8ca282 1173
bcostm 0:d83f1c8ca282 1174 DmaLeftRecHalfBuffCplt = 1;
bcostm 0:d83f1c8ca282 1175 }
bcostm 0:d83f1c8ca282 1176 else
bcostm 0:d83f1c8ca282 1177 {
bcostm 0:d83f1c8ca282 1178 if (DmaRightRecHalfBuffCplt)
bcostm 0:d83f1c8ca282 1179 {
bcostm 0:d83f1c8ca282 1180 BSP_ErrorHandler();
bcostm 0:d83f1c8ca282 1181 }
bcostm 0:d83f1c8ca282 1182
bcostm 0:d83f1c8ca282 1183 DmaRightRecHalfBuffCplt = 1;
bcostm 0:d83f1c8ca282 1184 }
bcostm 0:d83f1c8ca282 1185
bcostm 0:d83f1c8ca282 1186 if (((DmaLeftRecHalfBuffCplt != 0) && (DmaRightRecHalfBuffCplt != 0) && (hAudioIn.InputDevice == INPUT_DEVICE_DIGITAL_MIC)) ||
bcostm 0:d83f1c8ca282 1187 ((DmaLeftRecHalfBuffCplt != 0) && (hAudioIn.InputDevice == INPUT_DEVICE_DIGITAL_MIC1)) ||
bcostm 0:d83f1c8ca282 1188 ((DmaRightRecHalfBuffCplt != 0) && (hAudioIn.InputDevice == INPUT_DEVICE_DIGITAL_MIC2)))
bcostm 0:d83f1c8ca282 1189 {
bcostm 0:d83f1c8ca282 1190 hAudioIn.CbHalfTransfer();
bcostm 0:d83f1c8ca282 1191 DmaLeftRecHalfBuffCplt = 0;
bcostm 0:d83f1c8ca282 1192 DmaRightRecHalfBuffCplt = 0;
bcostm 0:d83f1c8ca282 1193 }
bcostm 0:d83f1c8ca282 1194 }
bcostm 0:d83f1c8ca282 1195 }
bcostm 0:d83f1c8ca282 1196
bcostm 0:d83f1c8ca282 1197 /**
bcostm 0:d83f1c8ca282 1198 * @brief Error callback.
bcostm 0:d83f1c8ca282 1199 * @param hdfsdm_filter : DFSDM filter handle.
bcostm 0:d83f1c8ca282 1200 * @retval None
bcostm 0:d83f1c8ca282 1201 */
bcostm 0:d83f1c8ca282 1202 void HAL_DFSDM_FilterErrorCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
bcostm 0:d83f1c8ca282 1203 {
bcostm 0:d83f1c8ca282 1204 /* Invoke the registered 'ErrorCallback' callback function (if any) */
bcostm 0:d83f1c8ca282 1205 if (hAudioIn.CbError != (Audio_CallbackTypeDef)NULL)
bcostm 0:d83f1c8ca282 1206 {
bcostm 0:d83f1c8ca282 1207 hAudioIn.CbError();
bcostm 0:d83f1c8ca282 1208 }
bcostm 0:d83f1c8ca282 1209 }
bcostm 0:d83f1c8ca282 1210
bcostm 0:d83f1c8ca282 1211 /**
bcostm 0:d83f1c8ca282 1212 * @brief SAI Rx Transfer completed callbacks.
bcostm 0:d83f1c8ca282 1213 * @param hsai: SAI handle
bcostm 0:d83f1c8ca282 1214 * @retval None
bcostm 0:d83f1c8ca282 1215 */
bcostm 0:d83f1c8ca282 1216 void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai)
bcostm 0:d83f1c8ca282 1217 {
bcostm 0:d83f1c8ca282 1218 /* Invoke the registered 'TransferComplete' function (if any) */
bcostm 0:d83f1c8ca282 1219 if (hAudioIn.CbTransferComplete != (Audio_CallbackTypeDef)NULL)
bcostm 0:d83f1c8ca282 1220 {
bcostm 0:d83f1c8ca282 1221 hAudioIn.CbTransferComplete();
bcostm 0:d83f1c8ca282 1222 }
bcostm 0:d83f1c8ca282 1223 }
bcostm 0:d83f1c8ca282 1224
bcostm 0:d83f1c8ca282 1225 /**
bcostm 0:d83f1c8ca282 1226 * @brief SAI Rx Half Transfer completed callbacks.
bcostm 0:d83f1c8ca282 1227 * @param hsai: SAI handle
bcostm 0:d83f1c8ca282 1228 * @retval None
bcostm 0:d83f1c8ca282 1229 */
bcostm 0:d83f1c8ca282 1230 void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai)
bcostm 0:d83f1c8ca282 1231 {
bcostm 0:d83f1c8ca282 1232 /* Invoke the registered 'HalfTransfer' callback function (if any) */
bcostm 0:d83f1c8ca282 1233 if (hAudioIn.CbHalfTransfer != (Audio_CallbackTypeDef)NULL)
bcostm 0:d83f1c8ca282 1234 {
bcostm 0:d83f1c8ca282 1235 hAudioIn.CbHalfTransfer();
bcostm 0:d83f1c8ca282 1236 }
bcostm 0:d83f1c8ca282 1237 }
bcostm 0:d83f1c8ca282 1238
bcostm 0:d83f1c8ca282 1239 /**
bcostm 0:d83f1c8ca282 1240 * @brief Stops audio recording.
bcostm 0:d83f1c8ca282 1241 * @retval BSP AUDIO status
bcostm 0:d83f1c8ca282 1242 */
bcostm 0:d83f1c8ca282 1243 uint8_t BSP_AUDIO_IN_Stop(void)
bcostm 0:d83f1c8ca282 1244 {
bcostm 0:d83f1c8ca282 1245 if (hAudioIn.InputDevice != INPUT_DEVICE_ANALOG_MIC)
bcostm 0:d83f1c8ca282 1246 {
bcostm 0:d83f1c8ca282 1247 if ((hAudioIn.InputDevice & INPUT_DEVICE_DIGITAL_MIC2) == INPUT_DEVICE_DIGITAL_MIC2)
bcostm 0:d83f1c8ca282 1248 {
bcostm 0:d83f1c8ca282 1249 /* Call the Media layer stop function for right channel */
bcostm 0:d83f1c8ca282 1250 if (HAL_DFSDM_FilterRegularStop_DMA(&BSP_AUDIO_hDfsdmRightFilter) != HAL_OK)
bcostm 0:d83f1c8ca282 1251 {
bcostm 0:d83f1c8ca282 1252 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1253 }
bcostm 0:d83f1c8ca282 1254 }
bcostm 0:d83f1c8ca282 1255 if ((hAudioIn.InputDevice & INPUT_DEVICE_DIGITAL_MIC1) == INPUT_DEVICE_DIGITAL_MIC1)
bcostm 0:d83f1c8ca282 1256 {
bcostm 0:d83f1c8ca282 1257 /* Call the Media layer stop function for left channel */
bcostm 0:d83f1c8ca282 1258 if (HAL_DFSDM_FilterRegularStop_DMA(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK)
bcostm 0:d83f1c8ca282 1259 {
bcostm 0:d83f1c8ca282 1260 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1261 }
bcostm 0:d83f1c8ca282 1262 }
bcostm 0:d83f1c8ca282 1263
bcostm 0:d83f1c8ca282 1264 if ((hAudioIn.InputDevice & INPUT_DEVICE_DIGITAL_MIC1) == INPUT_DEVICE_DIGITAL_MIC1)
bcostm 0:d83f1c8ca282 1265 {
bcostm 0:d83f1c8ca282 1266 /* Free hAudioIn.LeftRecBuff buffer */
bcostm 0:d83f1c8ca282 1267 #if defined(BSP_AUDIO_USE_RTOS)
bcostm 0:d83f1c8ca282 1268 k_free((void *)hAudioIn.LeftRecBuff);
bcostm 0:d83f1c8ca282 1269 #else
bcostm 0:d83f1c8ca282 1270 free((void *)hAudioIn.LeftRecBuff);
bcostm 0:d83f1c8ca282 1271 #endif
bcostm 0:d83f1c8ca282 1272 }
bcostm 0:d83f1c8ca282 1273 if ((hAudioIn.InputDevice & INPUT_DEVICE_DIGITAL_MIC2) == INPUT_DEVICE_DIGITAL_MIC2)
bcostm 0:d83f1c8ca282 1274 {
bcostm 0:d83f1c8ca282 1275 /* Free hAudioIn.RightRecBuff buffer */
bcostm 0:d83f1c8ca282 1276 #if defined(BSP_AUDIO_USE_RTOS)
bcostm 0:d83f1c8ca282 1277 k_free((void *)hAudioIn.RightRecBuff);
bcostm 0:d83f1c8ca282 1278 #else
bcostm 0:d83f1c8ca282 1279 free((void *)hAudioIn.RightRecBuff);
bcostm 0:d83f1c8ca282 1280 #endif
bcostm 0:d83f1c8ca282 1281 }
bcostm 0:d83f1c8ca282 1282 }
bcostm 0:d83f1c8ca282 1283 else
bcostm 0:d83f1c8ca282 1284 {
bcostm 0:d83f1c8ca282 1285 /* INPUT_DEVICE_ANALOG_MIC */
bcostm 0:d83f1c8ca282 1286 /* Call Audio Codec Stop function */
bcostm 0:d83f1c8ca282 1287 if (hAudioIn.AudioDrv->Stop(AUDIO_I2C_ADDRESS, CODEC_PDWN_HW) != 0)
bcostm 0:d83f1c8ca282 1288 {
bcostm 0:d83f1c8ca282 1289 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1290 }
bcostm 0:d83f1c8ca282 1291
bcostm 0:d83f1c8ca282 1292 /* Wait at least 100ms */
bcostm 0:d83f1c8ca282 1293 HAL_Delay(100);
bcostm 0:d83f1c8ca282 1294
bcostm 0:d83f1c8ca282 1295 /* Stop DMA transfer of PCM samples towards the serial audio interface */
bcostm 0:d83f1c8ca282 1296 if (HAL_SAI_DMAStop(&BSP_AUDIO_hSai_Rx) != HAL_OK)
bcostm 0:d83f1c8ca282 1297 {
bcostm 0:d83f1c8ca282 1298 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1299 }
bcostm 0:d83f1c8ca282 1300 }
bcostm 0:d83f1c8ca282 1301
bcostm 0:d83f1c8ca282 1302 return AUDIO_OK;
bcostm 0:d83f1c8ca282 1303 }
bcostm 0:d83f1c8ca282 1304
bcostm 0:d83f1c8ca282 1305 /**
bcostm 0:d83f1c8ca282 1306 * @brief Pauses the audio file stream.
bcostm 0:d83f1c8ca282 1307 * @retval BSP AUDIO status
bcostm 0:d83f1c8ca282 1308 */
bcostm 0:d83f1c8ca282 1309 uint8_t BSP_AUDIO_IN_Pause(void)
bcostm 0:d83f1c8ca282 1310 {
bcostm 0:d83f1c8ca282 1311 if (hAudioIn.InputDevice != INPUT_DEVICE_ANALOG_MIC)
bcostm 0:d83f1c8ca282 1312 {
bcostm 0:d83f1c8ca282 1313 /* Call the Media layer stop function */
bcostm 0:d83f1c8ca282 1314 if ((hAudioIn.InputDevice & INPUT_DEVICE_DIGITAL_MIC2) == INPUT_DEVICE_DIGITAL_MIC2)
bcostm 0:d83f1c8ca282 1315 {
bcostm 0:d83f1c8ca282 1316 if (HAL_DFSDM_FilterRegularStop_DMA(&BSP_AUDIO_hDfsdmRightFilter) != HAL_OK)
bcostm 0:d83f1c8ca282 1317 {
bcostm 0:d83f1c8ca282 1318 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1319 }
bcostm 0:d83f1c8ca282 1320 }
bcostm 0:d83f1c8ca282 1321
bcostm 0:d83f1c8ca282 1322 if ((hAudioIn.InputDevice & INPUT_DEVICE_DIGITAL_MIC1) == INPUT_DEVICE_DIGITAL_MIC1)
bcostm 0:d83f1c8ca282 1323 {
bcostm 0:d83f1c8ca282 1324 if (HAL_DFSDM_FilterRegularStop_DMA(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK)
bcostm 0:d83f1c8ca282 1325 {
bcostm 0:d83f1c8ca282 1326 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1327 }
bcostm 0:d83f1c8ca282 1328 }
bcostm 0:d83f1c8ca282 1329 }
bcostm 0:d83f1c8ca282 1330 else
bcostm 0:d83f1c8ca282 1331 {
bcostm 0:d83f1c8ca282 1332 /* INPUT_DEVICE_ANALOG_MIC */
bcostm 0:d83f1c8ca282 1333 /* Pause DMA transfer of PCM samples towards the serial audio interface */
bcostm 0:d83f1c8ca282 1334 if (HAL_SAI_DMAPause(&BSP_AUDIO_hSai_Rx) != HAL_OK)
bcostm 0:d83f1c8ca282 1335 {
bcostm 0:d83f1c8ca282 1336 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1337 }
bcostm 0:d83f1c8ca282 1338 }
bcostm 0:d83f1c8ca282 1339
bcostm 0:d83f1c8ca282 1340 return AUDIO_OK;
bcostm 0:d83f1c8ca282 1341 }
bcostm 0:d83f1c8ca282 1342
bcostm 0:d83f1c8ca282 1343 /**
bcostm 0:d83f1c8ca282 1344 * @brief Resumes the audio file stream.
bcostm 0:d83f1c8ca282 1345 * @retval BSP AUDIO status
bcostm 0:d83f1c8ca282 1346 */
bcostm 0:d83f1c8ca282 1347 uint8_t BSP_AUDIO_IN_Resume(void)
bcostm 0:d83f1c8ca282 1348 {
bcostm 0:d83f1c8ca282 1349 if (hAudioIn.InputDevice != INPUT_DEVICE_ANALOG_MIC)
bcostm 0:d83f1c8ca282 1350 {
bcostm 0:d83f1c8ca282 1351 if ((hAudioIn.InputDevice & INPUT_DEVICE_DIGITAL_MIC2) == INPUT_DEVICE_DIGITAL_MIC2)
bcostm 0:d83f1c8ca282 1352 {
bcostm 0:d83f1c8ca282 1353 /* Call the Media layer start function for right channel */
bcostm 0:d83f1c8ca282 1354 if (HAL_DFSDM_FilterRegularStart_DMA(&BSP_AUDIO_hDfsdmRightFilter,
bcostm 0:d83f1c8ca282 1355 (int32_t *)hAudioIn.RightRecBuff,
bcostm 0:d83f1c8ca282 1356 (hAudioIn.RecSize / hAudioIn.ChannelNbr)) != HAL_OK)
bcostm 0:d83f1c8ca282 1357 {
bcostm 0:d83f1c8ca282 1358 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1359 }
bcostm 0:d83f1c8ca282 1360 }
bcostm 0:d83f1c8ca282 1361
bcostm 0:d83f1c8ca282 1362 if ((hAudioIn.InputDevice & INPUT_DEVICE_DIGITAL_MIC1) == INPUT_DEVICE_DIGITAL_MIC1)
bcostm 0:d83f1c8ca282 1363 {
bcostm 0:d83f1c8ca282 1364 /* Call the Media layer start function for left channel */
bcostm 0:d83f1c8ca282 1365 if (HAL_DFSDM_FilterRegularStart_DMA(&BSP_AUDIO_hDfsdmLeftFilter,
bcostm 0:d83f1c8ca282 1366 (int32_t *)hAudioIn.LeftRecBuff,
bcostm 0:d83f1c8ca282 1367 (hAudioIn.RecSize / hAudioIn.ChannelNbr)) != HAL_OK)
bcostm 0:d83f1c8ca282 1368 {
bcostm 0:d83f1c8ca282 1369 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1370 }
bcostm 0:d83f1c8ca282 1371 }
bcostm 0:d83f1c8ca282 1372 }
bcostm 0:d83f1c8ca282 1373 else
bcostm 0:d83f1c8ca282 1374 {
bcostm 0:d83f1c8ca282 1375 /* INPUT_DEVICE_ANALOG_MIC */
bcostm 0:d83f1c8ca282 1376 /* Resume DMA transfer of PCM samples towards the serial audio interface */
bcostm 0:d83f1c8ca282 1377 if (HAL_SAI_DMAResume(&BSP_AUDIO_hSai_Rx) != HAL_OK)
bcostm 0:d83f1c8ca282 1378 {
bcostm 0:d83f1c8ca282 1379 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1380 }
bcostm 0:d83f1c8ca282 1381 }
bcostm 0:d83f1c8ca282 1382
bcostm 0:d83f1c8ca282 1383 return AUDIO_OK;
bcostm 0:d83f1c8ca282 1384 }
bcostm 0:d83f1c8ca282 1385
bcostm 0:d83f1c8ca282 1386 /**
bcostm 0:d83f1c8ca282 1387 * @brief register user callback functions
bcostm 0:d83f1c8ca282 1388 * @param ErrorCallback: pointer to the error callback function
bcostm 0:d83f1c8ca282 1389 * @param HalfTransferCallback: pointer to the half transfer callback function
bcostm 0:d83f1c8ca282 1390 * @param TransferCompleteCallback: pointer to the transfer complete callback function
bcostm 0:d83f1c8ca282 1391 * @retval None
bcostm 0:d83f1c8ca282 1392 */
bcostm 0:d83f1c8ca282 1393 void BSP_AUDIO_IN_RegisterCallbacks(Audio_CallbackTypeDef ErrorCallback,
bcostm 0:d83f1c8ca282 1394 Audio_CallbackTypeDef HalfTransferCallback,
bcostm 0:d83f1c8ca282 1395 Audio_CallbackTypeDef TransferCompleteCallback)
bcostm 0:d83f1c8ca282 1396 {
bcostm 0:d83f1c8ca282 1397 hAudioIn.CbError = ErrorCallback;
bcostm 0:d83f1c8ca282 1398 hAudioIn.CbHalfTransfer = HalfTransferCallback;
bcostm 0:d83f1c8ca282 1399 hAudioIn.CbTransferComplete = TransferCompleteCallback;
bcostm 0:d83f1c8ca282 1400 }
bcostm 0:d83f1c8ca282 1401 /**
bcostm 0:d83f1c8ca282 1402 * @}
bcostm 0:d83f1c8ca282 1403 */
bcostm 0:d83f1c8ca282 1404
bcostm 0:d83f1c8ca282 1405 /* private functions --------------------------------------------------------*/
bcostm 0:d83f1c8ca282 1406 /** @addtogroup STM32L496G_DISCOVERY_AUDIO_Private_Functions
bcostm 0:d83f1c8ca282 1407 * @{
bcostm 0:d83f1c8ca282 1408 */
bcostm 0:d83f1c8ca282 1409 /**
bcostm 0:d83f1c8ca282 1410 * @brief Initializes the Audio Codec audio interface (SAI).
bcostm 0:d83f1c8ca282 1411 * @param AudioFreq: Audio frequency to be configured for the SAI peripheral.
bcostm 0:d83f1c8ca282 1412 * @retval BSP AUDIO status
bcostm 0:d83f1c8ca282 1413 */
bcostm 0:d83f1c8ca282 1414 static uint8_t AUDIO_SAIx_Init(uint32_t AudioFreq)
bcostm 0:d83f1c8ca282 1415 {
bcostm 0:d83f1c8ca282 1416 uint8_t TxData[2] = {0x00, 0x00};
bcostm 0:d83f1c8ca282 1417
bcostm 0:d83f1c8ca282 1418 /* Initialize the BSP_AUDIO_hSai_Xx instances parameter */
bcostm 0:d83f1c8ca282 1419 BSP_AUDIO_hSai_Tx.Instance = SAI1_Block_A;
bcostm 0:d83f1c8ca282 1420 BSP_AUDIO_hSai_Rx.Instance = SAI1_Block_B;
bcostm 0:d83f1c8ca282 1421
bcostm 0:d83f1c8ca282 1422 /* Disable SAI peripheral to allow access to SAI internal registers */
bcostm 0:d83f1c8ca282 1423 __HAL_SAI_DISABLE(&BSP_AUDIO_hSai_Tx);
bcostm 0:d83f1c8ca282 1424 __HAL_SAI_DISABLE(&BSP_AUDIO_hSai_Rx);
bcostm 0:d83f1c8ca282 1425
bcostm 0:d83f1c8ca282 1426 /*******************************/
bcostm 0:d83f1c8ca282 1427 /* SAI block used for playback */
bcostm 0:d83f1c8ca282 1428 /*******************************/
bcostm 0:d83f1c8ca282 1429 /* Configure SAI_Block_x used for transmit
bcostm 0:d83f1c8ca282 1430 LSBFirst: Disabled
bcostm 0:d83f1c8ca282 1431 DataSize: 16 */
bcostm 0:d83f1c8ca282 1432 BSP_AUDIO_hSai_Tx.Init.AudioMode = SAI_MODEMASTER_TX;
bcostm 0:d83f1c8ca282 1433 BSP_AUDIO_hSai_Tx.Init.Synchro = SAI_ASYNCHRONOUS;
bcostm 0:d83f1c8ca282 1434 BSP_AUDIO_hSai_Tx.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
bcostm 0:d83f1c8ca282 1435 BSP_AUDIO_hSai_Tx.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
bcostm 0:d83f1c8ca282 1436 BSP_AUDIO_hSai_Tx.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
bcostm 0:d83f1c8ca282 1437 BSP_AUDIO_hSai_Tx.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
bcostm 0:d83f1c8ca282 1438 BSP_AUDIO_hSai_Tx.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_MCKDIV;
bcostm 0:d83f1c8ca282 1439 BSP_AUDIO_hSai_Tx.Init.Mckdiv = SAIClockDivider(AudioFreq);
bcostm 0:d83f1c8ca282 1440 BSP_AUDIO_hSai_Tx.Init.MonoStereoMode = SAI_STEREOMODE;
bcostm 0:d83f1c8ca282 1441 BSP_AUDIO_hSai_Tx.Init.CompandingMode = SAI_NOCOMPANDING;
bcostm 0:d83f1c8ca282 1442 BSP_AUDIO_hSai_Tx.Init.TriState = SAI_OUTPUT_NOTRELEASED;
bcostm 0:d83f1c8ca282 1443 BSP_AUDIO_hSai_Tx.Init.Protocol = SAI_FREE_PROTOCOL;
bcostm 0:d83f1c8ca282 1444 BSP_AUDIO_hSai_Tx.Init.DataSize = SAI_DATASIZE_16;
bcostm 0:d83f1c8ca282 1445 BSP_AUDIO_hSai_Tx.Init.FirstBit = SAI_FIRSTBIT_MSB;
bcostm 0:d83f1c8ca282 1446 BSP_AUDIO_hSai_Tx.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
bcostm 0:d83f1c8ca282 1447
bcostm 0:d83f1c8ca282 1448 /* Configure SAI_Block_x Frame
bcostm 0:d83f1c8ca282 1449 Frame Length: 32
bcostm 0:d83f1c8ca282 1450 Frame active Length: 16
bcostm 0:d83f1c8ca282 1451 FS Definition: Start frame + Channel Side identification
bcostm 0:d83f1c8ca282 1452 FS Polarity: FS active Low
bcostm 0:d83f1c8ca282 1453 FS Offset: FS asserted one bit before the first bit of slot 0 */
bcostm 0:d83f1c8ca282 1454 BSP_AUDIO_hSai_Tx.FrameInit.FrameLength = 32;
bcostm 0:d83f1c8ca282 1455 BSP_AUDIO_hSai_Tx.FrameInit.ActiveFrameLength = 16;
bcostm 0:d83f1c8ca282 1456 BSP_AUDIO_hSai_Tx.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
bcostm 0:d83f1c8ca282 1457 BSP_AUDIO_hSai_Tx.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
bcostm 0:d83f1c8ca282 1458 BSP_AUDIO_hSai_Tx.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
bcostm 0:d83f1c8ca282 1459
bcostm 0:d83f1c8ca282 1460 /* Configure SAI Block_x Slot
bcostm 0:d83f1c8ca282 1461 Slot First Bit Offset: 0
bcostm 0:d83f1c8ca282 1462 Slot Size : 16
bcostm 0:d83f1c8ca282 1463 Slot Number: 2
bcostm 0:d83f1c8ca282 1464 Slot Active: Slots 0 and 1 actives */
bcostm 0:d83f1c8ca282 1465 BSP_AUDIO_hSai_Tx.SlotInit.FirstBitOffset = 0;
bcostm 0:d83f1c8ca282 1466 BSP_AUDIO_hSai_Tx.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
bcostm 0:d83f1c8ca282 1467 BSP_AUDIO_hSai_Tx.SlotInit.SlotNumber = 2;
bcostm 0:d83f1c8ca282 1468 BSP_AUDIO_hSai_Tx.SlotInit.SlotActive = SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1;
bcostm 0:d83f1c8ca282 1469
bcostm 0:d83f1c8ca282 1470 /*****************************/
bcostm 0:d83f1c8ca282 1471 /* SAI block used for record */
bcostm 0:d83f1c8ca282 1472 /*****************************/
bcostm 0:d83f1c8ca282 1473 /* Configure SAI_Block_x used for receive
bcostm 0:d83f1c8ca282 1474 LSBFirst: Disabled
bcostm 0:d83f1c8ca282 1475 DataSize: 16 */
bcostm 0:d83f1c8ca282 1476 BSP_AUDIO_hSai_Rx.Init.AudioMode = SAI_MODESLAVE_RX;
bcostm 0:d83f1c8ca282 1477 BSP_AUDIO_hSai_Rx.Init.Synchro = SAI_SYNCHRONOUS;
bcostm 0:d83f1c8ca282 1478 BSP_AUDIO_hSai_Rx.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
bcostm 0:d83f1c8ca282 1479 BSP_AUDIO_hSai_Rx.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
bcostm 0:d83f1c8ca282 1480 BSP_AUDIO_hSai_Rx.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
bcostm 0:d83f1c8ca282 1481 BSP_AUDIO_hSai_Rx.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
bcostm 0:d83f1c8ca282 1482 BSP_AUDIO_hSai_Rx.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_MCKDIV;
bcostm 0:d83f1c8ca282 1483 BSP_AUDIO_hSai_Rx.Init.Mckdiv = SAIClockDivider(AudioFreq);
bcostm 0:d83f1c8ca282 1484 BSP_AUDIO_hSai_Rx.Init.MonoStereoMode = SAI_MONOMODE;
bcostm 0:d83f1c8ca282 1485 BSP_AUDIO_hSai_Rx.Init.CompandingMode = SAI_NOCOMPANDING;
bcostm 0:d83f1c8ca282 1486 BSP_AUDIO_hSai_Rx.Init.TriState = SAI_OUTPUT_NOTRELEASED;
bcostm 0:d83f1c8ca282 1487 BSP_AUDIO_hSai_Rx.Init.Protocol = SAI_FREE_PROTOCOL;
bcostm 0:d83f1c8ca282 1488 BSP_AUDIO_hSai_Rx.Init.DataSize = SAI_DATASIZE_16;
bcostm 0:d83f1c8ca282 1489 BSP_AUDIO_hSai_Rx.Init.FirstBit = SAI_FIRSTBIT_MSB;
bcostm 0:d83f1c8ca282 1490 BSP_AUDIO_hSai_Rx.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
bcostm 0:d83f1c8ca282 1491
bcostm 0:d83f1c8ca282 1492 /* Configure SAI_Block_x Frame
bcostm 0:d83f1c8ca282 1493 Frame Length: 32
bcostm 0:d83f1c8ca282 1494 Frame active Length: 16
bcostm 0:d83f1c8ca282 1495 FS Definition: Start frame + Channel Side identification
bcostm 0:d83f1c8ca282 1496 FS Polarity: FS active Low
bcostm 0:d83f1c8ca282 1497 FS Offset: FS asserted one bit before the first bit of slot 0 */
bcostm 0:d83f1c8ca282 1498 BSP_AUDIO_hSai_Rx.FrameInit.FrameLength = 32;
bcostm 0:d83f1c8ca282 1499 BSP_AUDIO_hSai_Rx.FrameInit.ActiveFrameLength = 16;
bcostm 0:d83f1c8ca282 1500 BSP_AUDIO_hSai_Rx.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
bcostm 0:d83f1c8ca282 1501 BSP_AUDIO_hSai_Rx.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
bcostm 0:d83f1c8ca282 1502 BSP_AUDIO_hSai_Rx.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
bcostm 0:d83f1c8ca282 1503
bcostm 0:d83f1c8ca282 1504 /* Configure SAI Block_x Slot
bcostm 0:d83f1c8ca282 1505 Slot First Bit Offset: 0
bcostm 0:d83f1c8ca282 1506 Slot Size : 16
bcostm 0:d83f1c8ca282 1507 Slot Number: 2
bcostm 0:d83f1c8ca282 1508 Slot Active: Slots 0 and 1 actives */
bcostm 0:d83f1c8ca282 1509 BSP_AUDIO_hSai_Rx.SlotInit.FirstBitOffset = 0;
bcostm 0:d83f1c8ca282 1510 BSP_AUDIO_hSai_Rx.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
bcostm 0:d83f1c8ca282 1511 BSP_AUDIO_hSai_Rx.SlotInit.SlotNumber = 2;
bcostm 0:d83f1c8ca282 1512 BSP_AUDIO_hSai_Rx.SlotInit.SlotActive = SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1;
bcostm 0:d83f1c8ca282 1513
bcostm 0:d83f1c8ca282 1514 /*********************************/
bcostm 0:d83f1c8ca282 1515 /* Initializes the SAI peripheral*/
bcostm 0:d83f1c8ca282 1516 /*********************************/
bcostm 0:d83f1c8ca282 1517 if (HAL_SAI_Init(&BSP_AUDIO_hSai_Tx) != HAL_OK)
bcostm 0:d83f1c8ca282 1518 {
bcostm 0:d83f1c8ca282 1519 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1520 }
bcostm 0:d83f1c8ca282 1521 if (HAL_SAI_Init(&BSP_AUDIO_hSai_Rx) != HAL_OK)
bcostm 0:d83f1c8ca282 1522 {
bcostm 0:d83f1c8ca282 1523 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1524 }
bcostm 0:d83f1c8ca282 1525
bcostm 0:d83f1c8ca282 1526 /******************************************/
bcostm 0:d83f1c8ca282 1527 /* Enable SAI peripheral to generate MCLK */
bcostm 0:d83f1c8ca282 1528 /******************************************/
bcostm 0:d83f1c8ca282 1529 __HAL_SAI_ENABLE(&BSP_AUDIO_hSai_Tx);
bcostm 0:d83f1c8ca282 1530 /* Transmit one byte to start FS generation */
bcostm 0:d83f1c8ca282 1531 if (HAL_SAI_Transmit(&BSP_AUDIO_hSai_Tx, TxData, 2, 1000) != HAL_OK)
bcostm 0:d83f1c8ca282 1532 {
bcostm 0:d83f1c8ca282 1533 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1534 }
bcostm 0:d83f1c8ca282 1535
bcostm 0:d83f1c8ca282 1536 return AUDIO_OK;
bcostm 0:d83f1c8ca282 1537 }
bcostm 0:d83f1c8ca282 1538
bcostm 0:d83f1c8ca282 1539 /**
bcostm 0:d83f1c8ca282 1540 * @brief De-initializes the Audio Codec audio interface (SAI).
bcostm 0:d83f1c8ca282 1541 * @retval BSP AUDIO status
bcostm 0:d83f1c8ca282 1542 */
bcostm 0:d83f1c8ca282 1543 static uint8_t AUDIO_SAIx_DeInit(void)
bcostm 0:d83f1c8ca282 1544 {
bcostm 0:d83f1c8ca282 1545 /* Disable the SAI audio block */
bcostm 0:d83f1c8ca282 1546 __HAL_SAI_DISABLE(&BSP_AUDIO_hSai_Tx);
bcostm 0:d83f1c8ca282 1547 __HAL_SAI_DISABLE(&BSP_AUDIO_hSai_Rx);
bcostm 0:d83f1c8ca282 1548
bcostm 0:d83f1c8ca282 1549 /* De-initializes the SAI peripheral */
bcostm 0:d83f1c8ca282 1550 if (HAL_SAI_DeInit(&BSP_AUDIO_hSai_Tx) != HAL_OK)
bcostm 0:d83f1c8ca282 1551 {
bcostm 0:d83f1c8ca282 1552 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1553 }
bcostm 0:d83f1c8ca282 1554 if (HAL_SAI_DeInit(&BSP_AUDIO_hSai_Rx) != HAL_OK)
bcostm 0:d83f1c8ca282 1555 {
bcostm 0:d83f1c8ca282 1556 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1557 }
bcostm 0:d83f1c8ca282 1558
bcostm 0:d83f1c8ca282 1559 return AUDIO_OK;
bcostm 0:d83f1c8ca282 1560 }
bcostm 0:d83f1c8ca282 1561
bcostm 0:d83f1c8ca282 1562 /**
bcostm 0:d83f1c8ca282 1563 * @brief SAI MSP Init
bcostm 0:d83f1c8ca282 1564 * @param hsai : pointer to a SAI_HandleTypeDef structure
bcostm 0:d83f1c8ca282 1565 * @retval None
bcostm 0:d83f1c8ca282 1566 */
bcostm 0:d83f1c8ca282 1567 void HAL_SAI_MspInit(SAI_HandleTypeDef *hsai)
bcostm 0:d83f1c8ca282 1568 {
bcostm 0:d83f1c8ca282 1569 GPIO_InitTypeDef GPIO_InitStruct;
bcostm 0:d83f1c8ca282 1570
bcostm 0:d83f1c8ca282 1571 /* Enable SAI clock */
bcostm 0:d83f1c8ca282 1572 __HAL_RCC_SAI1_CLK_ENABLE();
bcostm 0:d83f1c8ca282 1573
bcostm 0:d83f1c8ca282 1574 if (hsai->Instance == SAI1_Block_A)
bcostm 0:d83f1c8ca282 1575 {
bcostm 0:d83f1c8ca282 1576 /* SAI pins configuration: FS, SCK, MCLK and SD pins */
bcostm 0:d83f1c8ca282 1577 __HAL_RCC_GPIOB_CLK_ENABLE();
bcostm 0:d83f1c8ca282 1578 __HAL_RCC_GPIOE_CLK_ENABLE();
bcostm 0:d83f1c8ca282 1579 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
bcostm 0:d83f1c8ca282 1580 GPIO_InitStruct.Pull = GPIO_NOPULL;
bcostm 0:d83f1c8ca282 1581 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
bcostm 0:d83f1c8ca282 1582 GPIO_InitStruct.Alternate = GPIO_AF13_SAI1;
bcostm 0:d83f1c8ca282 1583 GPIO_InitStruct.Pin = GPIO_PIN_2;
bcostm 0:d83f1c8ca282 1584 HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); /* SAI1_MCLK_A */
bcostm 0:d83f1c8ca282 1585 GPIO_InitStruct.Pin = GPIO_PIN_4;
bcostm 0:d83f1c8ca282 1586 HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); /* SAI1_FS_A */
bcostm 0:d83f1c8ca282 1587 GPIO_InitStruct.Pin = GPIO_PIN_10;
bcostm 0:d83f1c8ca282 1588 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* SAI1_SCK_A */
bcostm 0:d83f1c8ca282 1589 GPIO_InitStruct.Pin = GPIO_PIN_6;
bcostm 0:d83f1c8ca282 1590 HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); /* SAI1_SD_A */
bcostm 0:d83f1c8ca282 1591
bcostm 0:d83f1c8ca282 1592 /* Configure the hDmaSaiTx handle parameters */
bcostm 0:d83f1c8ca282 1593 __HAL_RCC_DMA2_CLK_ENABLE();
bcostm 0:d83f1c8ca282 1594 hDmaSaiTx.Init.Request = DMA_REQUEST_1;
bcostm 0:d83f1c8ca282 1595 hDmaSaiTx.Init.Direction = DMA_MEMORY_TO_PERIPH;
bcostm 0:d83f1c8ca282 1596 hDmaSaiTx.Init.PeriphInc = DMA_PINC_DISABLE;
bcostm 0:d83f1c8ca282 1597 hDmaSaiTx.Init.MemInc = DMA_MINC_ENABLE;
bcostm 0:d83f1c8ca282 1598 hDmaSaiTx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
bcostm 0:d83f1c8ca282 1599 hDmaSaiTx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
bcostm 0:d83f1c8ca282 1600 hDmaSaiTx.Init.Mode = DMA_CIRCULAR;
bcostm 0:d83f1c8ca282 1601 hDmaSaiTx.Init.Priority = DMA_PRIORITY_HIGH;
bcostm 0:d83f1c8ca282 1602 hDmaSaiTx.Instance = DMA2_Channel1;
bcostm 0:d83f1c8ca282 1603 /* Associate the DMA handle */
bcostm 0:d83f1c8ca282 1604 __HAL_LINKDMA(hsai, hdmatx, hDmaSaiTx);
bcostm 0:d83f1c8ca282 1605 /* Deinitialize the Stream for new transfer */
bcostm 0:d83f1c8ca282 1606 HAL_DMA_DeInit(&hDmaSaiTx);
bcostm 0:d83f1c8ca282 1607 /* Configure the DMA Stream */
bcostm 0:d83f1c8ca282 1608 HAL_DMA_Init(&hDmaSaiTx);
bcostm 0:d83f1c8ca282 1609 /* SAI DMA IRQ Channel configuration */
bcostm 0:d83f1c8ca282 1610 HAL_NVIC_SetPriority(DMA2_Channel1_IRQn, 5, 0);
bcostm 0:d83f1c8ca282 1611 HAL_NVIC_EnableIRQ(DMA2_Channel1_IRQn);
bcostm 0:d83f1c8ca282 1612 }
bcostm 0:d83f1c8ca282 1613 else /* SAI1_BlockB */
bcostm 0:d83f1c8ca282 1614 {
bcostm 0:d83f1c8ca282 1615 /* SAI pins configuration: SD pin */
bcostm 0:d83f1c8ca282 1616 __HAL_RCC_GPIOE_CLK_ENABLE();
bcostm 0:d83f1c8ca282 1617 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
bcostm 0:d83f1c8ca282 1618 GPIO_InitStruct.Pull = GPIO_NOPULL;
bcostm 0:d83f1c8ca282 1619 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
bcostm 0:d83f1c8ca282 1620 GPIO_InitStruct.Alternate = GPIO_AF13_SAI1;
bcostm 0:d83f1c8ca282 1621 GPIO_InitStruct.Pin = GPIO_PIN_3;
bcostm 0:d83f1c8ca282 1622 HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); /* SAI1_SD_B */
bcostm 0:d83f1c8ca282 1623
bcostm 0:d83f1c8ca282 1624 /* Configure the hDmaSaiRx handle parameters */
bcostm 0:d83f1c8ca282 1625 __HAL_RCC_DMA2_CLK_ENABLE();
bcostm 0:d83f1c8ca282 1626 hDmaSaiRx.Init.Request = DMA_REQUEST_1;
bcostm 0:d83f1c8ca282 1627 hDmaSaiRx.Init.Direction = DMA_PERIPH_TO_MEMORY;
bcostm 0:d83f1c8ca282 1628 hDmaSaiRx.Init.PeriphInc = DMA_PINC_DISABLE;
bcostm 0:d83f1c8ca282 1629 hDmaSaiRx.Init.MemInc = DMA_MINC_ENABLE;
bcostm 0:d83f1c8ca282 1630 hDmaSaiRx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
bcostm 0:d83f1c8ca282 1631 hDmaSaiRx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
bcostm 0:d83f1c8ca282 1632 hDmaSaiRx.Init.Mode = DMA_CIRCULAR;
bcostm 0:d83f1c8ca282 1633 hDmaSaiRx.Init.Priority = DMA_PRIORITY_HIGH;
bcostm 0:d83f1c8ca282 1634 hDmaSaiRx.Instance = DMA2_Channel2;
bcostm 0:d83f1c8ca282 1635 /* Associate the DMA handle */
bcostm 0:d83f1c8ca282 1636 __HAL_LINKDMA(hsai, hdmarx, hDmaSaiRx);
bcostm 0:d83f1c8ca282 1637 /* Deinitialize the Stream for new transfer */
bcostm 0:d83f1c8ca282 1638 HAL_DMA_DeInit(&hDmaSaiRx);
bcostm 0:d83f1c8ca282 1639 /* Configure the DMA Stream */
bcostm 0:d83f1c8ca282 1640 HAL_DMA_Init(&hDmaSaiRx);
bcostm 0:d83f1c8ca282 1641 /* SAI DMA IRQ Channel configuration */
bcostm 0:d83f1c8ca282 1642 HAL_NVIC_SetPriority(DMA2_Channel2_IRQn, 5, 0);
bcostm 0:d83f1c8ca282 1643 HAL_NVIC_EnableIRQ(DMA2_Channel2_IRQn);
bcostm 0:d83f1c8ca282 1644 }
bcostm 0:d83f1c8ca282 1645 }
bcostm 0:d83f1c8ca282 1646
bcostm 0:d83f1c8ca282 1647 /**
bcostm 0:d83f1c8ca282 1648 * @brief SAI MSP De-init
bcostm 0:d83f1c8ca282 1649 * @param hsai : pointer to a SAI_HandleTypeDef structure
bcostm 0:d83f1c8ca282 1650 * @retval None
bcostm 0:d83f1c8ca282 1651 */
bcostm 0:d83f1c8ca282 1652 void HAL_SAI_MspDeInit(SAI_HandleTypeDef *hsai)
bcostm 0:d83f1c8ca282 1653 {
bcostm 0:d83f1c8ca282 1654 if (hsai->Instance == SAI1_Block_A)
bcostm 0:d83f1c8ca282 1655 {
bcostm 0:d83f1c8ca282 1656 /* Disable SAI DMA Channel IRQ */
bcostm 0:d83f1c8ca282 1657 HAL_NVIC_DisableIRQ(DMA2_Channel1_IRQn);
bcostm 0:d83f1c8ca282 1658
bcostm 0:d83f1c8ca282 1659 /* Reset the DMA Stream configuration*/
bcostm 0:d83f1c8ca282 1660 HAL_DMA_DeInit(&hDmaSaiTx);
bcostm 0:d83f1c8ca282 1661
bcostm 0:d83f1c8ca282 1662 /* De-initialize FS, SCK, MCK and SD pins*/
bcostm 0:d83f1c8ca282 1663 HAL_GPIO_DeInit(GPIOE, GPIO_PIN_2); /* SAI1_MCLK_A */
bcostm 0:d83f1c8ca282 1664 HAL_GPIO_DeInit(GPIOE, GPIO_PIN_4); /* SAI1_FS_A */
bcostm 0:d83f1c8ca282 1665 HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10); /* SAI1_SCK_A */
bcostm 0:d83f1c8ca282 1666 HAL_GPIO_DeInit(GPIOE, GPIO_PIN_6); /* SAI1_SD_A */
bcostm 0:d83f1c8ca282 1667
bcostm 0:d83f1c8ca282 1668 /* Don't disable SAI clock used for other SAI block */
bcostm 0:d83f1c8ca282 1669 /*__HAL_RCC_SAI1_CLK_DISABLE(); */
bcostm 0:d83f1c8ca282 1670 }
bcostm 0:d83f1c8ca282 1671 else /* SAI1_BlockB */
bcostm 0:d83f1c8ca282 1672 {
bcostm 0:d83f1c8ca282 1673 /* Disable SAI DMA Channel IRQ */
bcostm 0:d83f1c8ca282 1674 HAL_NVIC_DisableIRQ(DMA2_Channel2_IRQn);
bcostm 0:d83f1c8ca282 1675
bcostm 0:d83f1c8ca282 1676 /* Reset the DMA Stream configuration*/
bcostm 0:d83f1c8ca282 1677 HAL_DMA_DeInit(&hDmaSaiRx);
bcostm 0:d83f1c8ca282 1678
bcostm 0:d83f1c8ca282 1679 /* De-initialize SD pin */
bcostm 0:d83f1c8ca282 1680 HAL_GPIO_DeInit(GPIOE, GPIO_PIN_3); /* SAI1_SD_B */
bcostm 0:d83f1c8ca282 1681
bcostm 0:d83f1c8ca282 1682 /* Disable SAI clock */
bcostm 0:d83f1c8ca282 1683 __HAL_RCC_SAI1_CLK_DISABLE();
bcostm 0:d83f1c8ca282 1684 }
bcostm 0:d83f1c8ca282 1685 }
bcostm 0:d83f1c8ca282 1686
bcostm 0:d83f1c8ca282 1687 /**
bcostm 0:d83f1c8ca282 1688 * @}
bcostm 0:d83f1c8ca282 1689 */
bcostm 0:d83f1c8ca282 1690
bcostm 0:d83f1c8ca282 1691 /** @addtogroup STM32L496G_DISCOVERY_AUDIO_Private_Functions
bcostm 0:d83f1c8ca282 1692 * @{
bcostm 0:d83f1c8ca282 1693 */
bcostm 0:d83f1c8ca282 1694
bcostm 0:d83f1c8ca282 1695 /**
bcostm 0:d83f1c8ca282 1696 * @brief Initializes the Digital Filter for Sigma-Delta Modulators interface (DFSDM).
bcostm 0:d83f1c8ca282 1697 * @param AudioFreq: Audio frequency to be used to set correctly the DFSDM peripheral.
bcostm 0:d83f1c8ca282 1698 * @retval BSP AUDIO status
bcostm 0:d83f1c8ca282 1699 */
bcostm 0:d83f1c8ca282 1700 static uint8_t AUDIO_DFSDMx_Init(uint32_t AudioFreq)
bcostm 0:d83f1c8ca282 1701 {
bcostm 0:d83f1c8ca282 1702 if ((hAudioIn.InputDevice & INPUT_DEVICE_DIGITAL_MIC1) == INPUT_DEVICE_DIGITAL_MIC1)
bcostm 0:d83f1c8ca282 1703 {
bcostm 0:d83f1c8ca282 1704 /*####CHANNEL 3####*/
bcostm 0:d83f1c8ca282 1705 hAudioIn.hDfsdmLeftChannel.Init.OutputClock.Activation = ENABLE;
bcostm 0:d83f1c8ca282 1706 hAudioIn.hDfsdmLeftChannel.Init.OutputClock.Selection = DFSDM_CHANNEL_OUTPUT_CLOCK_AUDIO;
bcostm 0:d83f1c8ca282 1707 /* Set the DFSDM clock OUT audio frequency configuration */
bcostm 0:d83f1c8ca282 1708 hAudioIn.hDfsdmLeftChannel.Init.OutputClock.Divider = DFSDMClockDivider(AudioFreq);
bcostm 0:d83f1c8ca282 1709 hAudioIn.hDfsdmLeftChannel.Init.Input.Multiplexer = DFSDM_CHANNEL_EXTERNAL_INPUTS;
bcostm 0:d83f1c8ca282 1710 hAudioIn.hDfsdmLeftChannel.Init.Input.DataPacking = DFSDM_CHANNEL_STANDARD_MODE;
bcostm 0:d83f1c8ca282 1711 hAudioIn.hDfsdmLeftChannel.Init.Input.Pins = DFSDM_CHANNEL_SAME_CHANNEL_PINS;
bcostm 0:d83f1c8ca282 1712 /* Request to sample stable data for LEFT micro on Rising edge */
bcostm 0:d83f1c8ca282 1713 hAudioIn.hDfsdmLeftChannel.Init.SerialInterface.Type = DFSDM_CHANNEL_SPI_RISING;
bcostm 0:d83f1c8ca282 1714 hAudioIn.hDfsdmLeftChannel.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
bcostm 0:d83f1c8ca282 1715 hAudioIn.hDfsdmLeftChannel.Init.Awd.FilterOrder = DFSDM_CHANNEL_SINC1_ORDER;
bcostm 0:d83f1c8ca282 1716 hAudioIn.hDfsdmLeftChannel.Init.Awd.Oversampling = 10;
bcostm 0:d83f1c8ca282 1717 hAudioIn.hDfsdmLeftChannel.Init.Offset = 0;
bcostm 0:d83f1c8ca282 1718 hAudioIn.hDfsdmLeftChannel.Init.RightBitShift = DFSDMRightBitShift(AudioFreq);
bcostm 0:d83f1c8ca282 1719 hAudioIn.hDfsdmLeftChannel.Instance = DFSDM1_Channel3;
bcostm 0:d83f1c8ca282 1720
bcostm 0:d83f1c8ca282 1721 /* Init the DFSDM Channel */
bcostm 0:d83f1c8ca282 1722 if (HAL_DFSDM_ChannelInit(&hAudioIn.hDfsdmLeftChannel) != HAL_OK)
bcostm 0:d83f1c8ca282 1723 {
bcostm 0:d83f1c8ca282 1724 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1725 }
bcostm 0:d83f1c8ca282 1726 }
bcostm 0:d83f1c8ca282 1727
bcostm 0:d83f1c8ca282 1728 if ((hAudioIn.InputDevice & INPUT_DEVICE_DIGITAL_MIC2) == INPUT_DEVICE_DIGITAL_MIC2)
bcostm 0:d83f1c8ca282 1729 {
bcostm 0:d83f1c8ca282 1730 /*####CHANNEL 2####*/
bcostm 0:d83f1c8ca282 1731 hAudioIn.hDfsdmRightChannel.Init.OutputClock.Activation = ENABLE;
bcostm 0:d83f1c8ca282 1732 hAudioIn.hDfsdmRightChannel.Init.OutputClock.Selection = DFSDM_CHANNEL_OUTPUT_CLOCK_AUDIO;
bcostm 0:d83f1c8ca282 1733 /* Set the DFSDM clock OUT audio frequency configuration */
bcostm 0:d83f1c8ca282 1734 hAudioIn.hDfsdmRightChannel.Init.OutputClock.Divider = DFSDMClockDivider(AudioFreq);
bcostm 0:d83f1c8ca282 1735 hAudioIn.hDfsdmRightChannel.Init.Input.Multiplexer = DFSDM_CHANNEL_EXTERNAL_INPUTS;
bcostm 0:d83f1c8ca282 1736 hAudioIn.hDfsdmRightChannel.Init.Input.DataPacking = DFSDM_CHANNEL_STANDARD_MODE;
bcostm 0:d83f1c8ca282 1737 hAudioIn.hDfsdmRightChannel.Init.Input.Pins = DFSDM_CHANNEL_FOLLOWING_CHANNEL_PINS;
bcostm 0:d83f1c8ca282 1738 /* Request to sample stable data for LEFT micro on Rising edge */
bcostm 0:d83f1c8ca282 1739 hAudioIn.hDfsdmRightChannel.Init.SerialInterface.Type = DFSDM_CHANNEL_SPI_FALLING;
bcostm 0:d83f1c8ca282 1740 hAudioIn.hDfsdmRightChannel.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
bcostm 0:d83f1c8ca282 1741 hAudioIn.hDfsdmRightChannel.Init.Awd.FilterOrder = DFSDM_CHANNEL_SINC1_ORDER;
bcostm 0:d83f1c8ca282 1742 hAudioIn.hDfsdmRightChannel.Init.Awd.Oversampling = 10;
bcostm 0:d83f1c8ca282 1743 hAudioIn.hDfsdmRightChannel.Init.Offset = 0;
bcostm 0:d83f1c8ca282 1744 hAudioIn.hDfsdmRightChannel.Init.RightBitShift = DFSDMRightBitShift(AudioFreq);
bcostm 0:d83f1c8ca282 1745 hAudioIn.hDfsdmRightChannel.Instance = DFSDM1_Channel2;
bcostm 0:d83f1c8ca282 1746
bcostm 0:d83f1c8ca282 1747 /* Init the DFSDM Channel */
bcostm 0:d83f1c8ca282 1748 if (HAL_DFSDM_ChannelInit(&hAudioIn.hDfsdmRightChannel) != HAL_OK)
bcostm 0:d83f1c8ca282 1749 {
bcostm 0:d83f1c8ca282 1750 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1751 }
bcostm 0:d83f1c8ca282 1752 }
bcostm 0:d83f1c8ca282 1753
bcostm 0:d83f1c8ca282 1754 if ((hAudioIn.InputDevice & INPUT_DEVICE_DIGITAL_MIC1) == INPUT_DEVICE_DIGITAL_MIC1)
bcostm 0:d83f1c8ca282 1755 {
bcostm 0:d83f1c8ca282 1756 /*####FILTER 0####*/
bcostm 0:d83f1c8ca282 1757 BSP_AUDIO_hDfsdmLeftFilter.Init.RegularParam.Trigger = DFSDM_FILTER_SW_TRIGGER;
bcostm 0:d83f1c8ca282 1758 BSP_AUDIO_hDfsdmLeftFilter.Init.RegularParam.FastMode = ENABLE;
bcostm 0:d83f1c8ca282 1759 BSP_AUDIO_hDfsdmLeftFilter.Init.RegularParam.DmaMode = ENABLE;
bcostm 0:d83f1c8ca282 1760 BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.Trigger = DFSDM_FILTER_SW_TRIGGER;
bcostm 0:d83f1c8ca282 1761 BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.ScanMode = DISABLE;
bcostm 0:d83f1c8ca282 1762 BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.DmaMode = DISABLE;
bcostm 0:d83f1c8ca282 1763 BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.ExtTrigger = DFSDM_FILTER_EXT_TRIG_TIM8_TRGO;
bcostm 0:d83f1c8ca282 1764 BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.ExtTriggerEdge = DFSDM_FILTER_EXT_TRIG_BOTH_EDGES;
bcostm 0:d83f1c8ca282 1765 BSP_AUDIO_hDfsdmLeftFilter.Init.FilterParam.SincOrder = DFSDMFilterOrder(AudioFreq);
bcostm 0:d83f1c8ca282 1766 /* Set the DFSDM Filters Oversampling to have correct sample rate */
bcostm 0:d83f1c8ca282 1767 BSP_AUDIO_hDfsdmLeftFilter.Init.FilterParam.Oversampling = DFSDMOverSampling(AudioFreq);
bcostm 0:d83f1c8ca282 1768 BSP_AUDIO_hDfsdmLeftFilter.Init.FilterParam.IntOversampling = 1;
bcostm 0:d83f1c8ca282 1769 BSP_AUDIO_hDfsdmLeftFilter.Instance = DFSDM1_Filter0;
bcostm 0:d83f1c8ca282 1770
bcostm 0:d83f1c8ca282 1771 /* Init the DFSDM Filter */
bcostm 0:d83f1c8ca282 1772 if (HAL_DFSDM_FilterInit(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK)
bcostm 0:d83f1c8ca282 1773 {
bcostm 0:d83f1c8ca282 1774 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1775 }
bcostm 0:d83f1c8ca282 1776
bcostm 0:d83f1c8ca282 1777 /* Configure regular channel */
bcostm 0:d83f1c8ca282 1778 if (HAL_DFSDM_FilterConfigRegChannel(&BSP_AUDIO_hDfsdmLeftFilter,
bcostm 0:d83f1c8ca282 1779 DFSDM_CHANNEL_3,
bcostm 0:d83f1c8ca282 1780 DFSDM_CONTINUOUS_CONV_ON) != HAL_OK)
bcostm 0:d83f1c8ca282 1781 {
bcostm 0:d83f1c8ca282 1782 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1783 }
bcostm 0:d83f1c8ca282 1784 }
bcostm 0:d83f1c8ca282 1785
bcostm 0:d83f1c8ca282 1786 if ((hAudioIn.InputDevice & INPUT_DEVICE_DIGITAL_MIC2) == INPUT_DEVICE_DIGITAL_MIC2)
bcostm 0:d83f1c8ca282 1787 {
bcostm 0:d83f1c8ca282 1788 /*####FILTER 1####*/
bcostm 0:d83f1c8ca282 1789 if (hAudioIn.InputDevice == INPUT_DEVICE_DIGITAL_MIC2)
bcostm 0:d83f1c8ca282 1790 {
bcostm 0:d83f1c8ca282 1791 BSP_AUDIO_hDfsdmRightFilter.Init.RegularParam.Trigger = DFSDM_FILTER_SW_TRIGGER;
bcostm 0:d83f1c8ca282 1792 }
bcostm 0:d83f1c8ca282 1793 else
bcostm 0:d83f1c8ca282 1794 {
bcostm 0:d83f1c8ca282 1795 BSP_AUDIO_hDfsdmRightFilter.Init.RegularParam.Trigger = DFSDM_FILTER_SYNC_TRIGGER;
bcostm 0:d83f1c8ca282 1796 }
bcostm 0:d83f1c8ca282 1797 BSP_AUDIO_hDfsdmRightFilter.Init.RegularParam.FastMode = ENABLE;
bcostm 0:d83f1c8ca282 1798 BSP_AUDIO_hDfsdmRightFilter.Init.RegularParam.DmaMode = ENABLE;
bcostm 0:d83f1c8ca282 1799 BSP_AUDIO_hDfsdmRightFilter.Init.InjectedParam.Trigger = DFSDM_FILTER_SW_TRIGGER;
bcostm 0:d83f1c8ca282 1800 BSP_AUDIO_hDfsdmRightFilter.Init.InjectedParam.ScanMode = DISABLE;
bcostm 0:d83f1c8ca282 1801 BSP_AUDIO_hDfsdmRightFilter.Init.InjectedParam.DmaMode = DISABLE;
bcostm 0:d83f1c8ca282 1802 BSP_AUDIO_hDfsdmRightFilter.Init.InjectedParam.ExtTrigger = DFSDM_FILTER_EXT_TRIG_TIM8_TRGO;
bcostm 0:d83f1c8ca282 1803 BSP_AUDIO_hDfsdmRightFilter.Init.InjectedParam.ExtTriggerEdge = DFSDM_FILTER_EXT_TRIG_BOTH_EDGES;
bcostm 0:d83f1c8ca282 1804 BSP_AUDIO_hDfsdmRightFilter.Init.FilterParam.SincOrder = DFSDMFilterOrder(AudioFreq);
bcostm 0:d83f1c8ca282 1805 /* Set the DFSDM Filters Oversampling to have correct sample rate */
bcostm 0:d83f1c8ca282 1806 BSP_AUDIO_hDfsdmRightFilter.Init.FilterParam.Oversampling = DFSDMOverSampling(AudioFreq);
bcostm 0:d83f1c8ca282 1807 BSP_AUDIO_hDfsdmRightFilter.Init.FilterParam.IntOversampling = 1;
bcostm 0:d83f1c8ca282 1808 BSP_AUDIO_hDfsdmRightFilter.Instance = DFSDM1_Filter1;
bcostm 0:d83f1c8ca282 1809
bcostm 0:d83f1c8ca282 1810 /* Init the DFSDM Filter */
bcostm 0:d83f1c8ca282 1811 if (HAL_DFSDM_FilterInit(&BSP_AUDIO_hDfsdmRightFilter) != HAL_OK)
bcostm 0:d83f1c8ca282 1812 {
bcostm 0:d83f1c8ca282 1813 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1814 }
bcostm 0:d83f1c8ca282 1815
bcostm 0:d83f1c8ca282 1816 /* Configure regular channel */
bcostm 0:d83f1c8ca282 1817 if (HAL_DFSDM_FilterConfigRegChannel(&BSP_AUDIO_hDfsdmRightFilter,
bcostm 0:d83f1c8ca282 1818 DFSDM_CHANNEL_2,
bcostm 0:d83f1c8ca282 1819 DFSDM_CONTINUOUS_CONV_ON) != HAL_OK)
bcostm 0:d83f1c8ca282 1820 {
bcostm 0:d83f1c8ca282 1821 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1822 }
bcostm 0:d83f1c8ca282 1823 }
bcostm 0:d83f1c8ca282 1824
bcostm 0:d83f1c8ca282 1825 return AUDIO_OK;
bcostm 0:d83f1c8ca282 1826 }
bcostm 0:d83f1c8ca282 1827
bcostm 0:d83f1c8ca282 1828 /**
bcostm 0:d83f1c8ca282 1829 * @brief De-initializes the Digital Filter for Sigma-Delta Modulators interface (DFSDM).
bcostm 0:d83f1c8ca282 1830 * @retval BSP AUDIO status
bcostm 0:d83f1c8ca282 1831 */
bcostm 0:d83f1c8ca282 1832 static uint8_t AUDIO_DFSDMx_DeInit(void)
bcostm 0:d83f1c8ca282 1833 {
bcostm 0:d83f1c8ca282 1834 /* De-initializes the DFSDM filters to allow access to DFSDM internal registers */
bcostm 0:d83f1c8ca282 1835 if ((hAudioIn.InputDevice & INPUT_DEVICE_DIGITAL_MIC2) == INPUT_DEVICE_DIGITAL_MIC2)
bcostm 0:d83f1c8ca282 1836 {
bcostm 0:d83f1c8ca282 1837 if (HAL_DFSDM_FilterDeInit(&BSP_AUDIO_hDfsdmRightFilter) != HAL_OK)
bcostm 0:d83f1c8ca282 1838 {
bcostm 0:d83f1c8ca282 1839 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1840 }
bcostm 0:d83f1c8ca282 1841 }
bcostm 0:d83f1c8ca282 1842 if ((hAudioIn.InputDevice & INPUT_DEVICE_DIGITAL_MIC1) == INPUT_DEVICE_DIGITAL_MIC1)
bcostm 0:d83f1c8ca282 1843 {
bcostm 0:d83f1c8ca282 1844 if (HAL_DFSDM_FilterDeInit(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK)
bcostm 0:d83f1c8ca282 1845 {
bcostm 0:d83f1c8ca282 1846 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1847 }
bcostm 0:d83f1c8ca282 1848 }
bcostm 0:d83f1c8ca282 1849
bcostm 0:d83f1c8ca282 1850 /* De-initializes the DFSDM channels to allow access to DFSDM internal registers */
bcostm 0:d83f1c8ca282 1851 if ((hAudioIn.InputDevice & INPUT_DEVICE_DIGITAL_MIC2) == INPUT_DEVICE_DIGITAL_MIC2)
bcostm 0:d83f1c8ca282 1852 {
bcostm 0:d83f1c8ca282 1853 if (HAL_DFSDM_ChannelDeInit(&hAudioIn.hDfsdmRightChannel) != HAL_OK)
bcostm 0:d83f1c8ca282 1854 {
bcostm 0:d83f1c8ca282 1855 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1856 }
bcostm 0:d83f1c8ca282 1857 }
bcostm 0:d83f1c8ca282 1858 if ((hAudioIn.InputDevice & INPUT_DEVICE_DIGITAL_MIC1) == INPUT_DEVICE_DIGITAL_MIC1)
bcostm 0:d83f1c8ca282 1859 {
bcostm 0:d83f1c8ca282 1860 if (HAL_DFSDM_ChannelDeInit(&hAudioIn.hDfsdmLeftChannel) != HAL_OK)
bcostm 0:d83f1c8ca282 1861 {
bcostm 0:d83f1c8ca282 1862 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 1863 }
bcostm 0:d83f1c8ca282 1864 }
bcostm 0:d83f1c8ca282 1865
bcostm 0:d83f1c8ca282 1866 /* DFSDM reset */
bcostm 0:d83f1c8ca282 1867 __HAL_RCC_DFSDM1_FORCE_RESET();
bcostm 0:d83f1c8ca282 1868 __HAL_RCC_DFSDM1_RELEASE_RESET();
bcostm 0:d83f1c8ca282 1869
bcostm 0:d83f1c8ca282 1870 return AUDIO_OK;
bcostm 0:d83f1c8ca282 1871 }
bcostm 0:d83f1c8ca282 1872
bcostm 0:d83f1c8ca282 1873 /**
bcostm 0:d83f1c8ca282 1874 * @brief Initializes the DFSDM channel MSP.
bcostm 0:d83f1c8ca282 1875 * @param hdfsdm_channel : DFSDM channel handle.
bcostm 0:d83f1c8ca282 1876 * @retval None
bcostm 0:d83f1c8ca282 1877 */
bcostm 0:d83f1c8ca282 1878 void HAL_DFSDM_ChannelMspInit(DFSDM_Channel_HandleTypeDef *hdfsdm_channel)
bcostm 0:d83f1c8ca282 1879 {
bcostm 0:d83f1c8ca282 1880 if (((hdfsdm_channel->Instance == DFSDM1_Channel3) && ((hAudioIn.InputDevice & INPUT_DEVICE_DIGITAL_MIC1) != 0)) || \
bcostm 0:d83f1c8ca282 1881 ((hdfsdm_channel->Instance == DFSDM1_Channel2) && (hAudioIn.InputDevice == INPUT_DEVICE_DIGITAL_MIC2)))
bcostm 0:d83f1c8ca282 1882 {
bcostm 0:d83f1c8ca282 1883 GPIO_InitTypeDef GPIO_InitStruct;
bcostm 0:d83f1c8ca282 1884
bcostm 0:d83f1c8ca282 1885 /* Enable DFSDM clock */
bcostm 0:d83f1c8ca282 1886 __HAL_RCC_DFSDM1_CLK_ENABLE();
bcostm 0:d83f1c8ca282 1887
bcostm 0:d83f1c8ca282 1888 /* DFSDM pins configuration: DFSDM1_CKOUT, DFSDM1_DATIN3 pins */
bcostm 0:d83f1c8ca282 1889 __HAL_RCC_GPIOC_CLK_ENABLE();
bcostm 0:d83f1c8ca282 1890 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
bcostm 0:d83f1c8ca282 1891 GPIO_InitStruct.Pull = GPIO_NOPULL;
bcostm 0:d83f1c8ca282 1892 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
bcostm 0:d83f1c8ca282 1893 GPIO_InitStruct.Alternate = GPIO_AF6_DFSDM1;
bcostm 0:d83f1c8ca282 1894 GPIO_InitStruct.Pin = GPIO_PIN_2;
bcostm 0:d83f1c8ca282 1895 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /* DFSDM1_CKOUT */
bcostm 0:d83f1c8ca282 1896 GPIO_InitStruct.Pin = GPIO_PIN_7;
bcostm 0:d83f1c8ca282 1897 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /* DFSDM1_DATIN3 */
bcostm 0:d83f1c8ca282 1898
bcostm 0:d83f1c8ca282 1899 /* Enable MIC_VDD (PH1) */
bcostm 0:d83f1c8ca282 1900 __HAL_RCC_GPIOH_CLK_ENABLE();
bcostm 0:d83f1c8ca282 1901 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
bcostm 0:d83f1c8ca282 1902 GPIO_InitStruct.Pull = GPIO_NOPULL;
bcostm 0:d83f1c8ca282 1903 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
bcostm 0:d83f1c8ca282 1904 GPIO_InitStruct.Pin = GPIO_PIN_1;
bcostm 0:d83f1c8ca282 1905 HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
bcostm 0:d83f1c8ca282 1906 HAL_GPIO_WritePin(GPIOH, GPIO_PIN_1, GPIO_PIN_SET);
bcostm 0:d83f1c8ca282 1907 }
bcostm 0:d83f1c8ca282 1908 }
bcostm 0:d83f1c8ca282 1909
bcostm 0:d83f1c8ca282 1910 /**
bcostm 0:d83f1c8ca282 1911 * @brief De-initializes the DFSDM channel MSP.
bcostm 0:d83f1c8ca282 1912 * @param hdfsdm_channel : DFSDM channel handle.
bcostm 0:d83f1c8ca282 1913 * @retval None
bcostm 0:d83f1c8ca282 1914 */
bcostm 0:d83f1c8ca282 1915 void HAL_DFSDM_ChannelMspDeInit(DFSDM_Channel_HandleTypeDef *hdfsdm_channel)
bcostm 0:d83f1c8ca282 1916 {
bcostm 0:d83f1c8ca282 1917 if (((hdfsdm_channel->Instance == DFSDM1_Channel3) && ((hAudioIn.InputDevice & INPUT_DEVICE_DIGITAL_MIC1) != 0)) || \
bcostm 0:d83f1c8ca282 1918 ((hdfsdm_channel->Instance == DFSDM1_Channel2) && (hAudioIn.InputDevice == INPUT_DEVICE_DIGITAL_MIC2)))
bcostm 0:d83f1c8ca282 1919 {
bcostm 0:d83f1c8ca282 1920 /* Disable MIC_VDD (PH1) */
bcostm 0:d83f1c8ca282 1921 HAL_GPIO_WritePin(GPIOH, GPIO_PIN_1, GPIO_PIN_RESET);
bcostm 0:d83f1c8ca282 1922 HAL_GPIO_DeInit(GPIOH, GPIO_PIN_1);
bcostm 0:d83f1c8ca282 1923
bcostm 0:d83f1c8ca282 1924 /* De-initialize DFSDM1_CKOUT, DFSDM1_DATIN3 pins */
bcostm 0:d83f1c8ca282 1925 HAL_GPIO_DeInit(GPIOC, GPIO_PIN_2); /* DFSDM1_CKOUT */
bcostm 0:d83f1c8ca282 1926 HAL_GPIO_DeInit(GPIOC, GPIO_PIN_7); /* DFSDM1_DATIN3 */
bcostm 0:d83f1c8ca282 1927
bcostm 0:d83f1c8ca282 1928 /* Disable DFSDM1 */
bcostm 0:d83f1c8ca282 1929 __HAL_RCC_DFSDM1_CLK_DISABLE();
bcostm 0:d83f1c8ca282 1930 }
bcostm 0:d83f1c8ca282 1931 }
bcostm 0:d83f1c8ca282 1932
bcostm 0:d83f1c8ca282 1933 /**
bcostm 0:d83f1c8ca282 1934 * @brief Initializes the DFSDM filter MSP.
bcostm 0:d83f1c8ca282 1935 * @param hdfsdm_filter : DFSDM filter handle.
bcostm 0:d83f1c8ca282 1936 * @retval None
bcostm 0:d83f1c8ca282 1937 */
bcostm 0:d83f1c8ca282 1938 void HAL_DFSDM_FilterMspInit(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
bcostm 0:d83f1c8ca282 1939 {
bcostm 0:d83f1c8ca282 1940 if (hdfsdm_filter->Instance == DFSDM1_Filter0)
bcostm 0:d83f1c8ca282 1941 {
bcostm 0:d83f1c8ca282 1942 /* Enable the DMA clock */
bcostm 0:d83f1c8ca282 1943 __HAL_RCC_DMA1_CLK_ENABLE();
bcostm 0:d83f1c8ca282 1944
bcostm 0:d83f1c8ca282 1945 /* Configure the hAudioIn.hDmaDfsdmLeft handle parameters */
bcostm 0:d83f1c8ca282 1946 hAudioIn.hDmaDfsdmLeft.Init.Request = DMA_REQUEST_0;
bcostm 0:d83f1c8ca282 1947 hAudioIn.hDmaDfsdmLeft.Init.Direction = DMA_PERIPH_TO_MEMORY;
bcostm 0:d83f1c8ca282 1948 hAudioIn.hDmaDfsdmLeft.Init.PeriphInc = DMA_PINC_DISABLE;
bcostm 0:d83f1c8ca282 1949 hAudioIn.hDmaDfsdmLeft.Init.MemInc = DMA_MINC_ENABLE;
bcostm 0:d83f1c8ca282 1950 hAudioIn.hDmaDfsdmLeft.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
bcostm 0:d83f1c8ca282 1951 hAudioIn.hDmaDfsdmLeft.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
bcostm 0:d83f1c8ca282 1952 hAudioIn.hDmaDfsdmLeft.Init.Mode = DMA_CIRCULAR;
bcostm 0:d83f1c8ca282 1953 hAudioIn.hDmaDfsdmLeft.Init.Priority = DMA_PRIORITY_HIGH;
bcostm 0:d83f1c8ca282 1954 hAudioIn.hDmaDfsdmLeft.Instance = DMA1_Channel4;
bcostm 0:d83f1c8ca282 1955
bcostm 0:d83f1c8ca282 1956 /* Associate the DMA handle */
bcostm 0:d83f1c8ca282 1957 __HAL_LINKDMA(hdfsdm_filter, hdmaReg, hAudioIn.hDmaDfsdmLeft);
bcostm 0:d83f1c8ca282 1958
bcostm 0:d83f1c8ca282 1959 /* Reset DMA handle state */
bcostm 0:d83f1c8ca282 1960 __HAL_DMA_RESET_HANDLE_STATE(&hAudioIn.hDmaDfsdmLeft);
bcostm 0:d83f1c8ca282 1961
bcostm 0:d83f1c8ca282 1962 /* Configure the DMA Channel */
bcostm 0:d83f1c8ca282 1963 HAL_DMA_Init(&hAudioIn.hDmaDfsdmLeft);
bcostm 0:d83f1c8ca282 1964
bcostm 0:d83f1c8ca282 1965 /* DMA IRQ Channel configuration */
bcostm 0:d83f1c8ca282 1966 HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 5, 0);
bcostm 0:d83f1c8ca282 1967 HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn);
bcostm 0:d83f1c8ca282 1968 }
bcostm 0:d83f1c8ca282 1969 else /* DFSDM1_Filter1 */
bcostm 0:d83f1c8ca282 1970 {
bcostm 0:d83f1c8ca282 1971 if (hAudioIn.InputDevice == INPUT_DEVICE_DIGITAL_MIC2)
bcostm 0:d83f1c8ca282 1972 {
bcostm 0:d83f1c8ca282 1973 /* Enable the DMA clock needed if only MIC2 is used */
bcostm 0:d83f1c8ca282 1974 __HAL_RCC_DMA1_CLK_ENABLE();
bcostm 0:d83f1c8ca282 1975 }
bcostm 0:d83f1c8ca282 1976
bcostm 0:d83f1c8ca282 1977 /* Configure the hAudioIn.hDmaDfsdmRight handle parameters */
bcostm 0:d83f1c8ca282 1978 hAudioIn.hDmaDfsdmRight.Init.Request = DMA_REQUEST_0;
bcostm 0:d83f1c8ca282 1979 hAudioIn.hDmaDfsdmRight.Init.Direction = DMA_PERIPH_TO_MEMORY;
bcostm 0:d83f1c8ca282 1980 hAudioIn.hDmaDfsdmRight.Init.PeriphInc = DMA_PINC_DISABLE;
bcostm 0:d83f1c8ca282 1981 hAudioIn.hDmaDfsdmRight.Init.MemInc = DMA_MINC_ENABLE;
bcostm 0:d83f1c8ca282 1982 hAudioIn.hDmaDfsdmRight.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
bcostm 0:d83f1c8ca282 1983 hAudioIn.hDmaDfsdmRight.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
bcostm 0:d83f1c8ca282 1984 hAudioIn.hDmaDfsdmRight.Init.Mode = DMA_CIRCULAR;
bcostm 0:d83f1c8ca282 1985 hAudioIn.hDmaDfsdmRight.Init.Priority = DMA_PRIORITY_HIGH;
bcostm 0:d83f1c8ca282 1986 hAudioIn.hDmaDfsdmRight.Instance = DMA1_Channel5;
bcostm 0:d83f1c8ca282 1987
bcostm 0:d83f1c8ca282 1988 /* Associate the DMA handle */
bcostm 0:d83f1c8ca282 1989 __HAL_LINKDMA(hdfsdm_filter, hdmaReg, hAudioIn.hDmaDfsdmRight);
bcostm 0:d83f1c8ca282 1990
bcostm 0:d83f1c8ca282 1991 /* Reset DMA handle state */
bcostm 0:d83f1c8ca282 1992 __HAL_DMA_RESET_HANDLE_STATE(&hAudioIn.hDmaDfsdmRight);
bcostm 0:d83f1c8ca282 1993
bcostm 0:d83f1c8ca282 1994 /* Configure the DMA Channel */
bcostm 0:d83f1c8ca282 1995 HAL_DMA_Init(&hAudioIn.hDmaDfsdmRight);
bcostm 0:d83f1c8ca282 1996
bcostm 0:d83f1c8ca282 1997 /* DMA IRQ Channel configuration */
bcostm 0:d83f1c8ca282 1998 HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 5, 0);
bcostm 0:d83f1c8ca282 1999 HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);
bcostm 0:d83f1c8ca282 2000 }
bcostm 0:d83f1c8ca282 2001 }
bcostm 0:d83f1c8ca282 2002
bcostm 0:d83f1c8ca282 2003 /**
bcostm 0:d83f1c8ca282 2004 * @brief De-initializes the DFSDM filter MSP.
bcostm 0:d83f1c8ca282 2005 * @param hdfsdm_filter : DFSDM filter handle.
bcostm 0:d83f1c8ca282 2006 * @retval None
bcostm 0:d83f1c8ca282 2007 */
bcostm 0:d83f1c8ca282 2008 void HAL_DFSDM_FilterMspDeInit(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
bcostm 0:d83f1c8ca282 2009 {
bcostm 0:d83f1c8ca282 2010 if (hdfsdm_filter->Instance == DFSDM1_Filter0)
bcostm 0:d83f1c8ca282 2011 {
bcostm 0:d83f1c8ca282 2012 /* Disable DMA Channel IRQ */
bcostm 0:d83f1c8ca282 2013 HAL_NVIC_DisableIRQ(DMA1_Channel4_IRQn);
bcostm 0:d83f1c8ca282 2014
bcostm 0:d83f1c8ca282 2015 /* De-initialize the DMA Channel */
bcostm 0:d83f1c8ca282 2016 HAL_DMA_DeInit(&hAudioIn.hDmaDfsdmLeft);
bcostm 0:d83f1c8ca282 2017 }
bcostm 0:d83f1c8ca282 2018 else /* DFSDM1_Filter1 */
bcostm 0:d83f1c8ca282 2019 {
bcostm 0:d83f1c8ca282 2020 /* Disable DMA Channel IRQ */
bcostm 0:d83f1c8ca282 2021 HAL_NVIC_DisableIRQ(DMA1_Channel5_IRQn);
bcostm 0:d83f1c8ca282 2022
bcostm 0:d83f1c8ca282 2023 /* De-initialize the DMA Channel */
bcostm 0:d83f1c8ca282 2024 HAL_DMA_DeInit(&hAudioIn.hDmaDfsdmRight);
bcostm 0:d83f1c8ca282 2025 }
bcostm 0:d83f1c8ca282 2026 }
bcostm 0:d83f1c8ca282 2027
bcostm 0:d83f1c8ca282 2028 /**
bcostm 0:d83f1c8ca282 2029 * @brief Configures the SAI PLL clock according to the required audio frequency.
bcostm 0:d83f1c8ca282 2030 * @param Frequency: Audio frequency.
bcostm 0:d83f1c8ca282 2031 * @retval BSP AUDIO status
bcostm 0:d83f1c8ca282 2032 * @note The SAI PLL input clock must be configured in the user application.
bcostm 0:d83f1c8ca282 2033 * The SAI PLL configuration done within this function assumes that
bcostm 0:d83f1c8ca282 2034 * the SAI PLL input clock runs at 8 MHz.
bcostm 0:d83f1c8ca282 2035 */
bcostm 0:d83f1c8ca282 2036 static uint8_t AUDIO_SAIPLLConfig(uint32_t Frequency)
bcostm 0:d83f1c8ca282 2037 {
bcostm 0:d83f1c8ca282 2038 RCC_PeriphCLKInitTypeDef RCC_ExCLKInitStruct;
bcostm 0:d83f1c8ca282 2039
bcostm 0:d83f1c8ca282 2040 /* Retrieve actual RCC configuration */
bcostm 0:d83f1c8ca282 2041 HAL_RCCEx_GetPeriphCLKConfig(&RCC_ExCLKInitStruct);
bcostm 0:d83f1c8ca282 2042
bcostm 0:d83f1c8ca282 2043 if ((Frequency == AUDIO_FREQUENCY_11K)
bcostm 0:d83f1c8ca282 2044 || (Frequency == AUDIO_FREQUENCY_22K)
bcostm 0:d83f1c8ca282 2045 || (Frequency == AUDIO_FREQUENCY_44K))
bcostm 0:d83f1c8ca282 2046 {
bcostm 0:d83f1c8ca282 2047 /* Configure PLLSAI prescalers */
bcostm 0:d83f1c8ca282 2048 /* SAI clock config
bcostm 0:d83f1c8ca282 2049 PLLSAI2_VCO= 8 Mhz * PLLSAI1N = 8 * 24 = VCO_192M
bcostm 0:d83f1c8ca282 2050 SAI_CK_x = PLLSAI2_VCO/PLLSAI1P = 192/17 = 11.294 Mhz */
bcostm 0:d83f1c8ca282 2051 RCC_ExCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
bcostm 0:d83f1c8ca282 2052 RCC_ExCLKInitStruct.PLLSAI2.PLLSAI2N = 24;
bcostm 0:d83f1c8ca282 2053 RCC_ExCLKInitStruct.PLLSAI2.PLLSAI2P = 17;
bcostm 0:d83f1c8ca282 2054 RCC_ExCLKInitStruct.PLLSAI2.PLLSAI2ClockOut = RCC_PLLSAI2_SAI2CLK;
bcostm 0:d83f1c8ca282 2055 RCC_ExCLKInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI2;
bcostm 0:d83f1c8ca282 2056 }
bcostm 0:d83f1c8ca282 2057 else /* AUDIO_FREQUENCY_8K, AUDIO_FREQUENCY_16K, AUDIO_FREQUENCY_48K, AUDIO_FREQUENCY_96K */
bcostm 0:d83f1c8ca282 2058 {
bcostm 0:d83f1c8ca282 2059 /* SAI clock config
bcostm 0:d83f1c8ca282 2060 PLLSAI2_VCO= 8 Mhz * PLLSAI1N = 8 * 43 = VCO_344M
bcostm 0:d83f1c8ca282 2061 SAI_CK_x = PLLSAI1_VCO/PLLSAI2P = 344/7 = 49.142 Mhz */
bcostm 0:d83f1c8ca282 2062 RCC_ExCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
bcostm 0:d83f1c8ca282 2063 RCC_ExCLKInitStruct.PLLSAI2.PLLSAI2N = 43;
bcostm 0:d83f1c8ca282 2064 RCC_ExCLKInitStruct.PLLSAI2.PLLSAI2P = 7;
bcostm 0:d83f1c8ca282 2065 RCC_ExCLKInitStruct.PLLSAI2.PLLSAI2ClockOut = RCC_PLLSAI2_SAI2CLK;
bcostm 0:d83f1c8ca282 2066 RCC_ExCLKInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI2;
bcostm 0:d83f1c8ca282 2067 }
bcostm 0:d83f1c8ca282 2068
bcostm 0:d83f1c8ca282 2069 if (HAL_RCCEx_PeriphCLKConfig(&RCC_ExCLKInitStruct) != HAL_OK)
bcostm 0:d83f1c8ca282 2070 {
bcostm 0:d83f1c8ca282 2071 return AUDIO_ERROR;
bcostm 0:d83f1c8ca282 2072 }
bcostm 0:d83f1c8ca282 2073
bcostm 0:d83f1c8ca282 2074 return AUDIO_OK;
bcostm 0:d83f1c8ca282 2075 }
bcostm 0:d83f1c8ca282 2076
bcostm 0:d83f1c8ca282 2077 /**
bcostm 0:d83f1c8ca282 2078 * @}
bcostm 0:d83f1c8ca282 2079 */
bcostm 0:d83f1c8ca282 2080
bcostm 0:d83f1c8ca282 2081 /**
bcostm 0:d83f1c8ca282 2082 * @}
bcostm 0:d83f1c8ca282 2083 */
bcostm 0:d83f1c8ca282 2084
bcostm 0:d83f1c8ca282 2085 /**
bcostm 0:d83f1c8ca282 2086 * @}
bcostm 0:d83f1c8ca282 2087 */
bcostm 0:d83f1c8ca282 2088
bcostm 0:d83f1c8ca282 2089 /**
bcostm 0:d83f1c8ca282 2090 * @}
bcostm 0:d83f1c8ca282 2091 */
bcostm 0:d83f1c8ca282 2092
bcostm 0:d83f1c8ca282 2093 /**
bcostm 0:d83f1c8ca282 2094 * @}
bcostm 0:d83f1c8ca282 2095 */
bcostm 0:d83f1c8ca282 2096
bcostm 0:d83f1c8ca282 2097 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/