Audio Demo with DISCO Board, takes control samples, waits for user input, samples regularly.

Dependencies:   CMSIS_DSP_401 STM32L4xx_HAL_Driver mbed-src_DISO_AUDIO_DEMO

Committer:
EricLew
Date:
Sun Dec 13 19:12:11 2015 +0000
Revision:
0:3eee9435dd17
Audio Demo using DISCO Board

Who changed what in which revision?

UserRevisionLine numberNew contents of line
EricLew 0:3eee9435dd17 1 /**
EricLew 0:3eee9435dd17 2 ******************************************************************************
EricLew 0:3eee9435dd17 3 * @file stm32l476g_discovery_audio.c
EricLew 0:3eee9435dd17 4 * @author MCD Application Team
EricLew 0:3eee9435dd17 5 * @version V1.0.1
EricLew 0:3eee9435dd17 6 * @date 16-September-2015
EricLew 0:3eee9435dd17 7 * @brief This file provides a set of functions needed to manage the
EricLew 0:3eee9435dd17 8 * Audio driver for the STM32L476G-Discovery board.
EricLew 0:3eee9435dd17 9 ******************************************************************************
EricLew 0:3eee9435dd17 10 * @attention
EricLew 0:3eee9435dd17 11 *
EricLew 0:3eee9435dd17 12 * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
EricLew 0:3eee9435dd17 13 *
EricLew 0:3eee9435dd17 14 * Redistribution and use in source and binary forms, with or without modification,
EricLew 0:3eee9435dd17 15 * are permitted provided that the following conditions are met:
EricLew 0:3eee9435dd17 16 * 1. Redistributions of source code must retain the above copyright notice,
EricLew 0:3eee9435dd17 17 * this list of conditions and the following disclaimer.
EricLew 0:3eee9435dd17 18 * 2. Redistributions in binary form must reproduce the above copyright notice,
EricLew 0:3eee9435dd17 19 * this list of conditions and the following disclaimer in the documentation
EricLew 0:3eee9435dd17 20 * and/or other materials provided with the distribution.
EricLew 0:3eee9435dd17 21 * 3. Neither the name of STMicroelectronics nor the names of its contributors
EricLew 0:3eee9435dd17 22 * may be used to endorse or promote products derived from this software
EricLew 0:3eee9435dd17 23 * without specific prior written permission.
EricLew 0:3eee9435dd17 24 *
EricLew 0:3eee9435dd17 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
EricLew 0:3eee9435dd17 26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
EricLew 0:3eee9435dd17 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
EricLew 0:3eee9435dd17 28 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
EricLew 0:3eee9435dd17 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
EricLew 0:3eee9435dd17 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
EricLew 0:3eee9435dd17 31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
EricLew 0:3eee9435dd17 32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
EricLew 0:3eee9435dd17 33 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
EricLew 0:3eee9435dd17 34 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
EricLew 0:3eee9435dd17 35 *
EricLew 0:3eee9435dd17 36 ******************************************************************************
EricLew 0:3eee9435dd17 37 */
EricLew 0:3eee9435dd17 38
EricLew 0:3eee9435dd17 39 /*==============================================================================
EricLew 0:3eee9435dd17 40 User NOTES
EricLew 0:3eee9435dd17 41
EricLew 0:3eee9435dd17 42 1. How To use this driver:
EricLew 0:3eee9435dd17 43 --------------------------
EricLew 0:3eee9435dd17 44 + This driver supports STM32L4xx devices on STM32L476G-Discovery (MB1184) Discovery boards.
EricLew 0:3eee9435dd17 45 a) to play an audio file (all functions names start by BSP_AUDIO_OUT_xxx)
EricLew 0:3eee9435dd17 46 b) to record an audio file through MP34DT01TR, ST MEMS (all functions names start by BSP_AUDIO_IN_xxx)
EricLew 0:3eee9435dd17 47
EricLew 0:3eee9435dd17 48 a) PLAY A FILE:
EricLew 0:3eee9435dd17 49 ==============
EricLew 0:3eee9435dd17 50 + Call the function BSP_AUDIO_OUT_Init(
EricLew 0:3eee9435dd17 51 OutputDevice: physical output mode (OUTPUT_DEVICE_SPEAKER,
EricLew 0:3eee9435dd17 52 OUTPUT_DEVICE_HEADPHONE or OUTPUT_DEVICE_BOTH)
EricLew 0:3eee9435dd17 53 Volume : Initial volume to be set (0 is min (mute), 100 is max (100%)
EricLew 0:3eee9435dd17 54 AudioFreq : Audio frequency in Hz (8000, 16000, 22500, 32000...)
EricLew 0:3eee9435dd17 55 this parameter is relative to the audio file/stream type.
EricLew 0:3eee9435dd17 56 )
EricLew 0:3eee9435dd17 57 This function configures all the hardware required for the audio application (codec, I2C, SAI,
EricLew 0:3eee9435dd17 58 GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if configuration is OK.
EricLew 0:3eee9435dd17 59 If the returned value is different from AUDIO_OK or the function is stuck then the communication with
EricLew 0:3eee9435dd17 60 the audio codec has failed.
EricLew 0:3eee9435dd17 61 - OUTPUT_DEVICE_SPEAKER : only speaker will be set as output for the audio stream.
EricLew 0:3eee9435dd17 62 - OUTPUT_DEVICE_HEADPHONE: only headphones will be set as output for the audio stream.
EricLew 0:3eee9435dd17 63 - OUTPUT_DEVICE_BOTH : both Speaker and Headphone are used as outputs for the audio stream
EricLew 0:3eee9435dd17 64 at the same time.
EricLew 0:3eee9435dd17 65
EricLew 0:3eee9435dd17 66 + Call the function BSP_AUDIO_OUT_RegisterCallbacks to register user callbacks
EricLew 0:3eee9435dd17 67 required to manage audio data streaming towards the audio codec (ErrorCallback(),
EricLew 0:3eee9435dd17 68 HalfTransfer_CallBack() and TransferComplete_CallBack()).
EricLew 0:3eee9435dd17 69
EricLew 0:3eee9435dd17 70 + Call the function BSP_AUDIO_OUT_Play() to start audio playback (for the first time).
EricLew 0:3eee9435dd17 71 + Call the function BSP_AUDIO_OUT_Pause() to pause audio playabck
EricLew 0:3eee9435dd17 72 + Call the function BSP_AUDIO_OUT_Resume() to resume audio playback.
EricLew 0:3eee9435dd17 73 Note. After calling BSP_AUDIO_OUT_Pause() function for pause, only BSP_AUDIO_OUT_Resume() should be called
EricLew 0:3eee9435dd17 74 for resume (it is not allowed to call BSP_AUDIO_OUT_Play() in this case).
EricLew 0:3eee9435dd17 75 Note. This function should be called only when the audio file is played or paused (not stopped).
EricLew 0:3eee9435dd17 76 + Call the function BSP_AUDIO_OUT_Stop() to stop audio playback.
EricLew 0:3eee9435dd17 77 + To modify the volume level, the sampling frequency, the device output mode,
EricLew 0:3eee9435dd17 78 the mute status or the audio configuration or the stop, use the functions: BSP_AUDIO_OUT_SetVolume(),
EricLew 0:3eee9435dd17 79 AUDIO_OUT_SetFrequency(), BSP_AUDIO_OUT_SetOutputMode(), BSP_AUDIO_OUT_SetMute()and
EricLew 0:3eee9435dd17 80 BSP_AUDIO_OUT_ChangeAudioConfig().
EricLew 0:3eee9435dd17 81
EricLew 0:3eee9435dd17 82 Driver architecture:
EricLew 0:3eee9435dd17 83 --------------------
EricLew 0:3eee9435dd17 84 + This driver provides the audio layer high level API: it consists in functions
EricLew 0:3eee9435dd17 85 exported in the stm32l476g_discovery_audio.h file (e.g. BSP_AUDIO_OUT_Init(),
EricLew 0:3eee9435dd17 86 BSP_AUDIO_OUT_Play(), ...).
EricLew 0:3eee9435dd17 87 + This driver also includes the Media Access Layer (MAL): it consists in
EricLew 0:3eee9435dd17 88 functions allowing to access setup the audio devices. These functions
EricLew 0:3eee9435dd17 89 are included as local functions into the stm32l476g_discovery_audio.c file
EricLew 0:3eee9435dd17 90 (e.g. AUDIO_SAIx_Init()).
EricLew 0:3eee9435dd17 91
EricLew 0:3eee9435dd17 92 Known Limitations:
EricLew 0:3eee9435dd17 93 ------------------
EricLew 0:3eee9435dd17 94 1- Communication with the audio codec (through I2C) may be corrupted if it is interrupted by some
EricLew 0:3eee9435dd17 95 user interrupt routines (in this case, interrupts could be disabled just before the start of
EricLew 0:3eee9435dd17 96 communication then re-enabled when it is over). Note that this communication is only done at
EricLew 0:3eee9435dd17 97 the configuration phase (BSP_AUDIO_OUT_Init() or BSP_AUDIO_OUT_Stop()) and when Volume control modification is
EricLew 0:3eee9435dd17 98 performed (BSP_AUDIO_OUT_SetVolume() or BSP_AUDIO_OUT_SetMute()or BSP_AUDIO_OUT_SetOutputMode()).
EricLew 0:3eee9435dd17 99 When the audio data is played, no communication is required with the audio codec.
EricLew 0:3eee9435dd17 100 2- Parsing of audio file is not implemented (in order to determine audio file properties: Mono/Stereo, Data size,
EricLew 0:3eee9435dd17 101 File size, Audio Frequency, Audio Data header size ...). The configuration is fixed for the given audio file.
EricLew 0:3eee9435dd17 102 3- Supports only 16-bits audio data size.
EricLew 0:3eee9435dd17 103
EricLew 0:3eee9435dd17 104 b) RECORD A FILE:
EricLew 0:3eee9435dd17 105 ================
EricLew 0:3eee9435dd17 106 + Call the function BSP_AUDIO_IN_Init(
EricLew 0:3eee9435dd17 107 AudioFreq: Audio frequency in Hz (8000, 16000, 22500, 32000 ...)
EricLew 0:3eee9435dd17 108 )
EricLew 0:3eee9435dd17 109 This function configures all the hardware required for the audio application (DFSDM,
EricLew 0:3eee9435dd17 110 GPIOs, DMA and interrupt if needed). This function returns AUDIO_OK if the
EricLew 0:3eee9435dd17 111 configuration completes successfully.
EricLew 0:3eee9435dd17 112
EricLew 0:3eee9435dd17 113 + Call the function BSP_AUDIO_IN_RegisterCallbacks to register user callbacks
EricLew 0:3eee9435dd17 114 used to stream audio data toward the record buffer (ErrorCallback(),
EricLew 0:3eee9435dd17 115 HalfTransfer_CallBack() and TransferComplete_CallBack()).
EricLew 0:3eee9435dd17 116
EricLew 0:3eee9435dd17 117 + Call the function BSP_AUDIO_IN_Record(
EricLew 0:3eee9435dd17 118 pbuf Main buffer pointer for the recorded data storing
EricLew 0:3eee9435dd17 119 size Current size of the recorded buffer
EricLew 0:3eee9435dd17 120 )
EricLew 0:3eee9435dd17 121 to start recording from the microphone.
EricLew 0:3eee9435dd17 122
EricLew 0:3eee9435dd17 123 + Call the function AUDIO_IN_STOP() to stop recording
EricLew 0:3eee9435dd17 124 ==============================================================================*/
EricLew 0:3eee9435dd17 125
EricLew 0:3eee9435dd17 126 /* Includes ------------------------------------------------------------------*/
EricLew 0:3eee9435dd17 127 #include <string.h>
EricLew 0:3eee9435dd17 128 #include "stm32l476g_discovery_audio.h"
EricLew 0:3eee9435dd17 129
EricLew 0:3eee9435dd17 130 /** @addtogroup BSP
EricLew 0:3eee9435dd17 131 * @{
EricLew 0:3eee9435dd17 132 */
EricLew 0:3eee9435dd17 133
EricLew 0:3eee9435dd17 134 /** @addtogroup STM32L476G_DISCOVERY
EricLew 0:3eee9435dd17 135 * @{
EricLew 0:3eee9435dd17 136 */
EricLew 0:3eee9435dd17 137
EricLew 0:3eee9435dd17 138 /** @defgroup STM32L476G_DISCOVERY_AUDIO STM32L476G-DISCOVERY AUDIO
EricLew 0:3eee9435dd17 139 * @brief This file includes the low layer driver for cs43l22 Audio Codec
EricLew 0:3eee9435dd17 140 * available on STM32L476G-Discovery board(MB1184).
EricLew 0:3eee9435dd17 141 * @{
EricLew 0:3eee9435dd17 142 */
EricLew 0:3eee9435dd17 143
EricLew 0:3eee9435dd17 144 /* Private typedef -----------------------------------------------------------*/
EricLew 0:3eee9435dd17 145 /** @defgroup STM32L476G_DISCOVERY_AUDIO_Private_Types Private Types
EricLew 0:3eee9435dd17 146 * @{
EricLew 0:3eee9435dd17 147 */
EricLew 0:3eee9435dd17 148 typedef struct
EricLew 0:3eee9435dd17 149 {
EricLew 0:3eee9435dd17 150
EricLew 0:3eee9435dd17 151 Audio_CallbackTypeDef CbError; /* pointer to the callback function invoked when ... */
EricLew 0:3eee9435dd17 152 Audio_CallbackTypeDef CbHalfTransfer; /* pointer to the callback function invoked when ... */
EricLew 0:3eee9435dd17 153 Audio_CallbackTypeDef CbTransferComplete; /* pointer to the callback function invoked when ... */
EricLew 0:3eee9435dd17 154 } AUDIO_OUT_TypeDef;
EricLew 0:3eee9435dd17 155
EricLew 0:3eee9435dd17 156 typedef struct
EricLew 0:3eee9435dd17 157 {
EricLew 0:3eee9435dd17 158 DFSDM_Channel_HandleTypeDef hDfsdmLeftChannel; /* DFSDM channel handle used for left channel */
EricLew 0:3eee9435dd17 159 DMA_HandleTypeDef hDmaDfsdmLeft; /* DMA handle used for DFSDM regular conversions on left channel */
EricLew 0:3eee9435dd17 160 int32_t * LeftRecBuff; /* Buffers for left samples */
EricLew 0:3eee9435dd17 161 uint32_t Frequency; /* Record Frequency */
EricLew 0:3eee9435dd17 162 uint32_t BitResolution; /* Record bit resolution */
EricLew 0:3eee9435dd17 163 uint32_t ChannelNbr; /* Record Channel Number */
EricLew 0:3eee9435dd17 164 uint16_t * pRecBuf; /* Pointer to record user buffer */
EricLew 0:3eee9435dd17 165 uint32_t RecSize; /* Size to record in mono, double size to record in stereo */
EricLew 0:3eee9435dd17 166 Audio_CallbackTypeDef CbError; /* pointer to the callback function invoked when a DMA transfer fails */
EricLew 0:3eee9435dd17 167 Audio_CallbackTypeDef CbHalfTransfer; /* pointer to the callback function invoked when half of the DMA transfer is completed */
EricLew 0:3eee9435dd17 168 Audio_CallbackTypeDef CbTransferComplete; /* pointer to the callback function invoked when the DMA transfer is completed */
EricLew 0:3eee9435dd17 169 } AUDIO_IN_TypeDef;
EricLew 0:3eee9435dd17 170
EricLew 0:3eee9435dd17 171 /**
EricLew 0:3eee9435dd17 172 * @}
EricLew 0:3eee9435dd17 173 */
EricLew 0:3eee9435dd17 174
EricLew 0:3eee9435dd17 175 /* Private defines ------------------------------------------------------------*/
EricLew 0:3eee9435dd17 176 /** @defgroup STM32L476G_DISCOVERY_AUDIO_Private_Constants Private Constants
EricLew 0:3eee9435dd17 177 * @{
EricLew 0:3eee9435dd17 178 */
EricLew 0:3eee9435dd17 179 /**
EricLew 0:3eee9435dd17 180 * @}
EricLew 0:3eee9435dd17 181 */
EricLew 0:3eee9435dd17 182
EricLew 0:3eee9435dd17 183 /* Private macros ------------------------------------------------------------*/
EricLew 0:3eee9435dd17 184 /** @defgroup STM32L476G_DISCOVERY_AUDIO_Private_Macros Private Macros
EricLew 0:3eee9435dd17 185 * @{
EricLew 0:3eee9435dd17 186 */
EricLew 0:3eee9435dd17 187 /*### PLAY ###*/
EricLew 0:3eee9435dd17 188 /* SCK(kHz) = SAI_CK_x/(SAIClockDivider*2*256) */
EricLew 0:3eee9435dd17 189 #define SAIClockDivider(__FREQUENCY__) \
EricLew 0:3eee9435dd17 190 (__FREQUENCY__ == AUDIO_FREQUENCY_8K) ? 12 \
EricLew 0:3eee9435dd17 191 : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 2 \
EricLew 0:3eee9435dd17 192 : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 6 \
EricLew 0:3eee9435dd17 193 : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 1 \
EricLew 0:3eee9435dd17 194 : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 3 \
EricLew 0:3eee9435dd17 195 : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 0 \
EricLew 0:3eee9435dd17 196 : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 2 : 1 \
EricLew 0:3eee9435dd17 197
EricLew 0:3eee9435dd17 198 /*### RECORD ###*/
EricLew 0:3eee9435dd17 199 #define DFSDMOverSampling(__FREQUENCY__) \
EricLew 0:3eee9435dd17 200 (__FREQUENCY__ == AUDIO_FREQUENCY_8K) ? 256 \
EricLew 0:3eee9435dd17 201 : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 256 \
EricLew 0:3eee9435dd17 202 : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 128 \
EricLew 0:3eee9435dd17 203 : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 128 \
EricLew 0:3eee9435dd17 204 : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 64 \
EricLew 0:3eee9435dd17 205 : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 64 \
EricLew 0:3eee9435dd17 206 : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 32 : 16 \
EricLew 0:3eee9435dd17 207
EricLew 0:3eee9435dd17 208 #define DFSDMClockDivider(__FREQUENCY__) \
EricLew 0:3eee9435dd17 209 (__FREQUENCY__ == AUDIO_FREQUENCY_8K) ? 24 \
EricLew 0:3eee9435dd17 210 : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 4 \
EricLew 0:3eee9435dd17 211 : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 24 \
EricLew 0:3eee9435dd17 212 : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 4 \
EricLew 0:3eee9435dd17 213 : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 24 \
EricLew 0:3eee9435dd17 214 : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 4 \
EricLew 0:3eee9435dd17 215 : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 32 : 32 \
EricLew 0:3eee9435dd17 216
EricLew 0:3eee9435dd17 217 #define DFSDMFilterOrder(__FREQUENCY__) \
EricLew 0:3eee9435dd17 218 (__FREQUENCY__ == AUDIO_FREQUENCY_8K) ? DFSDM_FILTER_SINC3_ORDER \
EricLew 0:3eee9435dd17 219 : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? DFSDM_FILTER_SINC3_ORDER \
EricLew 0:3eee9435dd17 220 : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? DFSDM_FILTER_SINC3_ORDER \
EricLew 0:3eee9435dd17 221 : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? DFSDM_FILTER_SINC3_ORDER \
EricLew 0:3eee9435dd17 222 : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? DFSDM_FILTER_SINC4_ORDER \
EricLew 0:3eee9435dd17 223 : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? DFSDM_FILTER_SINC4_ORDER \
EricLew 0:3eee9435dd17 224 : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? DFSDM_FILTER_SINC4_ORDER : DFSDM_FILTER_SINC5_ORDER \
EricLew 0:3eee9435dd17 225
EricLew 0:3eee9435dd17 226 #define DFSDMRightBitShift(__FREQUENCY__) \
EricLew 0:3eee9435dd17 227 (__FREQUENCY__ == AUDIO_FREQUENCY_8K) ? 2 \
EricLew 0:3eee9435dd17 228 : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 3 \
EricLew 0:3eee9435dd17 229 : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 3 \
EricLew 0:3eee9435dd17 230 : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 0 \
EricLew 0:3eee9435dd17 231 : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 3 \
EricLew 0:3eee9435dd17 232 : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 3 \
EricLew 0:3eee9435dd17 233 : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 7 : 0 \
EricLew 0:3eee9435dd17 234
EricLew 0:3eee9435dd17 235 /* Saturate the record PCM sample */
EricLew 0:3eee9435dd17 236 #define SaturaLH(N, L, H) (((N)<(L))?(L):(((N)>(H))?(H):(N)))
EricLew 0:3eee9435dd17 237
EricLew 0:3eee9435dd17 238 /**
EricLew 0:3eee9435dd17 239 * @}
EricLew 0:3eee9435dd17 240 */
EricLew 0:3eee9435dd17 241
EricLew 0:3eee9435dd17 242 /* Private variables ---------------------------------------------------------*/
EricLew 0:3eee9435dd17 243 /** @defgroup STM32L476G_DISCOVERY_AUDIO_Private_Variables Private Variables
EricLew 0:3eee9435dd17 244 * @{
EricLew 0:3eee9435dd17 245 */
EricLew 0:3eee9435dd17 246 /* Audio output context information */
EricLew 0:3eee9435dd17 247 static AUDIO_OUT_TypeDef hAudioOut;
EricLew 0:3eee9435dd17 248
EricLew 0:3eee9435dd17 249 /* Audio input context information */
EricLew 0:3eee9435dd17 250 static AUDIO_IN_TypeDef hAudioIn;
EricLew 0:3eee9435dd17 251
EricLew 0:3eee9435dd17 252 /* SAI DMA handle */
EricLew 0:3eee9435dd17 253 static DMA_HandleTypeDef hDmaSai;
EricLew 0:3eee9435dd17 254 /**
EricLew 0:3eee9435dd17 255 * @}
EricLew 0:3eee9435dd17 256 */
EricLew 0:3eee9435dd17 257
EricLew 0:3eee9435dd17 258 /* Exported variables ---------------------------------------------------------*/
EricLew 0:3eee9435dd17 259 /** @defgroup STM32L476G_DISCOVERY_AUDIO_Exported_Variables Exported Variables
EricLew 0:3eee9435dd17 260 * @{
EricLew 0:3eee9435dd17 261 */
EricLew 0:3eee9435dd17 262 /* SAIx handle */
EricLew 0:3eee9435dd17 263 SAI_HandleTypeDef BSP_AUDIO_hSai;
EricLew 0:3eee9435dd17 264
EricLew 0:3eee9435dd17 265 /* DFSDM filter handle */
EricLew 0:3eee9435dd17 266 DFSDM_Filter_HandleTypeDef BSP_AUDIO_hDfsdmLeftFilter;
EricLew 0:3eee9435dd17 267 /**
EricLew 0:3eee9435dd17 268 * @}
EricLew 0:3eee9435dd17 269 */
EricLew 0:3eee9435dd17 270
EricLew 0:3eee9435dd17 271 /* Private function prototypes -----------------------------------------------*/
EricLew 0:3eee9435dd17 272 /** @defgroup STM32L476G_DISCOVERY_AUDIO_Private_Functions Private Functions
EricLew 0:3eee9435dd17 273 * @{
EricLew 0:3eee9435dd17 274 */
EricLew 0:3eee9435dd17 275 static void AUDIO_CODEC_Reset(void);
EricLew 0:3eee9435dd17 276 static uint8_t AUDIO_SAIx_Init(uint32_t AudioFreq);
EricLew 0:3eee9435dd17 277 static uint8_t AUDIO_SAIx_DeInit(void);
EricLew 0:3eee9435dd17 278 static uint8_t AUDIO_DFSDMx_Init(uint32_t AudioFreq);
EricLew 0:3eee9435dd17 279 static uint8_t AUDIO_DFSDMx_DeInit(void);
EricLew 0:3eee9435dd17 280 static uint8_t AUDIO_SAIPLLConfig(uint32_t AudioFreq);
EricLew 0:3eee9435dd17 281 /**
EricLew 0:3eee9435dd17 282 * @}
EricLew 0:3eee9435dd17 283 */
EricLew 0:3eee9435dd17 284
EricLew 0:3eee9435dd17 285 /* Exported functions --------------------------------------------------------*/
EricLew 0:3eee9435dd17 286 /** @addtogroup STM32L476G_DISCOVERY_AUDIO_Exported_Functions
EricLew 0:3eee9435dd17 287 * @{
EricLew 0:3eee9435dd17 288 */
EricLew 0:3eee9435dd17 289
EricLew 0:3eee9435dd17 290 /**
EricLew 0:3eee9435dd17 291 * @brief Configures the audio codec related peripherals.
EricLew 0:3eee9435dd17 292 * @param OutputDevice: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE,
EricLew 0:3eee9435dd17 293 * or OUTPUT_DEVICE_BOTH.
EricLew 0:3eee9435dd17 294 * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max))
EricLew 0:3eee9435dd17 295 * @param AudioFreq: Audio frequency used to play the audio stream.ion.
EricLew 0:3eee9435dd17 296 * @retval BSP AUDIO status
EricLew 0:3eee9435dd17 297 * @note The SAI PLL input clock must be configure in the user application.
EricLew 0:3eee9435dd17 298 * The SAI PLL configuration done within this function assumes that
EricLew 0:3eee9435dd17 299 * the SAI PLL input clock runs at 8 MHz.
EricLew 0:3eee9435dd17 300 */
EricLew 0:3eee9435dd17 301
EricLew 0:3eee9435dd17 302 /**
EricLew 0:3eee9435dd17 303 * @brief Tx Transfer completed callbacks.
EricLew 0:3eee9435dd17 304 * @param hsai: SAI handle
EricLew 0:3eee9435dd17 305 * @retval None
EricLew 0:3eee9435dd17 306 */
EricLew 0:3eee9435dd17 307 void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
EricLew 0:3eee9435dd17 308 {
EricLew 0:3eee9435dd17 309 /* Invoke the registered 'TransferComplete' function (if any) */
EricLew 0:3eee9435dd17 310 if (hAudioOut.CbTransferComplete != (Audio_CallbackTypeDef)NULL)
EricLew 0:3eee9435dd17 311 {
EricLew 0:3eee9435dd17 312 hAudioOut.CbTransferComplete();
EricLew 0:3eee9435dd17 313 }
EricLew 0:3eee9435dd17 314 }
EricLew 0:3eee9435dd17 315
EricLew 0:3eee9435dd17 316 /**
EricLew 0:3eee9435dd17 317 * @brief Tx Half Transfer completed callbacks.
EricLew 0:3eee9435dd17 318 * @param hsai: SAI handle
EricLew 0:3eee9435dd17 319 * @retval None
EricLew 0:3eee9435dd17 320 */
EricLew 0:3eee9435dd17 321 void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
EricLew 0:3eee9435dd17 322 {
EricLew 0:3eee9435dd17 323 /* Invoke the registered 'HalfTransfer' callback function (if any) */
EricLew 0:3eee9435dd17 324 if (hAudioOut.CbHalfTransfer != (Audio_CallbackTypeDef)NULL)
EricLew 0:3eee9435dd17 325 {
EricLew 0:3eee9435dd17 326 hAudioOut.CbHalfTransfer();
EricLew 0:3eee9435dd17 327 }
EricLew 0:3eee9435dd17 328 }
EricLew 0:3eee9435dd17 329
EricLew 0:3eee9435dd17 330 /**
EricLew 0:3eee9435dd17 331 * @brief SAI error callbacks.
EricLew 0:3eee9435dd17 332 * @param hsai: SAI handle
EricLew 0:3eee9435dd17 333 * @retval None
EricLew 0:3eee9435dd17 334 */
EricLew 0:3eee9435dd17 335 void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai)
EricLew 0:3eee9435dd17 336 {
EricLew 0:3eee9435dd17 337 /* Invoke the registered 'ErrorCallback' callback function (if any) */
EricLew 0:3eee9435dd17 338 if (hAudioOut.CbError != (Audio_CallbackTypeDef)NULL)
EricLew 0:3eee9435dd17 339 {
EricLew 0:3eee9435dd17 340 hAudioOut.CbError();
EricLew 0:3eee9435dd17 341 }
EricLew 0:3eee9435dd17 342 }
EricLew 0:3eee9435dd17 343
EricLew 0:3eee9435dd17 344 /**
EricLew 0:3eee9435dd17 345 * @}
EricLew 0:3eee9435dd17 346 */
EricLew 0:3eee9435dd17 347
EricLew 0:3eee9435dd17 348 /** @addtogroup STM32L476G_EVAL_AUDIO_Exported_Functions
EricLew 0:3eee9435dd17 349 * @{
EricLew 0:3eee9435dd17 350 */
EricLew 0:3eee9435dd17 351
EricLew 0:3eee9435dd17 352 /**
EricLew 0:3eee9435dd17 353 * @brief Initializes micropone related peripherals.
EricLew 0:3eee9435dd17 354 * @note This function assumes that the SAI input clock (through PLL_M)
EricLew 0:3eee9435dd17 355 * is already configured and ready to be used.
EricLew 0:3eee9435dd17 356 * @param AudioFreq: Audio frequency to be configured for the SAI peripheral.
EricLew 0:3eee9435dd17 357 * @param BitRes: Audio frequency to be configured for the SAI peripheral.
EricLew 0:3eee9435dd17 358 * @param ChnlNbr: Audio frequency to be configured for the SAI peripheral.
EricLew 0:3eee9435dd17 359 * @retval BSP AUDIO status
EricLew 0:3eee9435dd17 360 */
EricLew 0:3eee9435dd17 361 uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
EricLew 0:3eee9435dd17 362 {
EricLew 0:3eee9435dd17 363 /* Update the audio input context */
EricLew 0:3eee9435dd17 364 hAudioIn.Frequency = AudioFreq;
EricLew 0:3eee9435dd17 365 hAudioIn.BitResolution = BitRes;
EricLew 0:3eee9435dd17 366 hAudioIn.ChannelNbr = ChnlNbr;
EricLew 0:3eee9435dd17 367 hAudioIn.CbError = (Audio_CallbackTypeDef)NULL;
EricLew 0:3eee9435dd17 368 hAudioIn.CbHalfTransfer = (Audio_CallbackTypeDef)NULL;
EricLew 0:3eee9435dd17 369 hAudioIn.CbTransferComplete = (Audio_CallbackTypeDef)NULL;
EricLew 0:3eee9435dd17 370
EricLew 0:3eee9435dd17 371 /* Configure the SAI PLL according to the requested audio frequency */
EricLew 0:3eee9435dd17 372 if (AUDIO_SAIPLLConfig(AudioFreq) != AUDIO_OK)
EricLew 0:3eee9435dd17 373 {
EricLew 0:3eee9435dd17 374 return AUDIO_ERROR;
EricLew 0:3eee9435dd17 375 }
EricLew 0:3eee9435dd17 376
EricLew 0:3eee9435dd17 377 /* Initializes the Digital Filter for Sigma-Delta Modulators interface */
EricLew 0:3eee9435dd17 378 if(AUDIO_DFSDMx_Init(AudioFreq) != AUDIO_OK)
EricLew 0:3eee9435dd17 379 {
EricLew 0:3eee9435dd17 380 return AUDIO_ERROR;
EricLew 0:3eee9435dd17 381 }
EricLew 0:3eee9435dd17 382
EricLew 0:3eee9435dd17 383 return AUDIO_OK;
EricLew 0:3eee9435dd17 384 }
EricLew 0:3eee9435dd17 385
EricLew 0:3eee9435dd17 386 /**
EricLew 0:3eee9435dd17 387 * @brief De-Initializes microphone related peripherals.
EricLew 0:3eee9435dd17 388 * @retval BSP AUDIO status
EricLew 0:3eee9435dd17 389
EricLew 0:3eee9435dd17 390 */
EricLew 0:3eee9435dd17 391 uint8_t BSP_AUDIO_IN_DeInit(void)
EricLew 0:3eee9435dd17 392 {
EricLew 0:3eee9435dd17 393 /* De-initializes the Digital Filter for Sigma-Delta Modulators interface */
EricLew 0:3eee9435dd17 394 if (AUDIO_DFSDMx_DeInit() != AUDIO_OK)
EricLew 0:3eee9435dd17 395 {
EricLew 0:3eee9435dd17 396 return AUDIO_ERROR;
EricLew 0:3eee9435dd17 397 }
EricLew 0:3eee9435dd17 398
EricLew 0:3eee9435dd17 399 /* Reset the audio input context */
EricLew 0:3eee9435dd17 400 memset(&hAudioIn, 0, sizeof(hAudioIn));
EricLew 0:3eee9435dd17 401
EricLew 0:3eee9435dd17 402 return AUDIO_OK;
EricLew 0:3eee9435dd17 403 }
EricLew 0:3eee9435dd17 404
EricLew 0:3eee9435dd17 405 /**
EricLew 0:3eee9435dd17 406 * @brief Starts audio recording.
EricLew 0:3eee9435dd17 407 * @param pbuf: Main buffer pointer for the recorded data storing
EricLew 0:3eee9435dd17 408 * @param size: Current size of the recorded buffer
EricLew 0:3eee9435dd17 409 * @note The Right channel is start at first with synchro on start of Left channel
EricLew 0:3eee9435dd17 410 * @retval BSP AUDIO status
EricLew 0:3eee9435dd17 411 */
EricLew 0:3eee9435dd17 412 uint8_t BSP_AUDIO_IN_Record(uint16_t* pbuf, uint32_t size)
EricLew 0:3eee9435dd17 413 {
EricLew 0:3eee9435dd17 414 hAudioIn.pRecBuf = pbuf;
EricLew 0:3eee9435dd17 415 hAudioIn.RecSize = size;
EricLew 0:3eee9435dd17 416
EricLew 0:3eee9435dd17 417 /* Allocate hAudioIn.LeftRecBuff buffer */
EricLew 0:3eee9435dd17 418 #if defined(BSP_AUDIO_USE_RTOS)
EricLew 0:3eee9435dd17 419 hAudioIn.LeftRecBuff = (int32_t *)k_malloc(size * sizeof(int32_t));
EricLew 0:3eee9435dd17 420 #else
EricLew 0:3eee9435dd17 421 hAudioIn.LeftRecBuff = (int32_t *)malloc(size * sizeof(int32_t));
EricLew 0:3eee9435dd17 422 #endif
EricLew 0:3eee9435dd17 423 if(hAudioIn.LeftRecBuff == NULL)
EricLew 0:3eee9435dd17 424 {
EricLew 0:3eee9435dd17 425 return AUDIO_ERROR;
EricLew 0:3eee9435dd17 426 }
EricLew 0:3eee9435dd17 427
EricLew 0:3eee9435dd17 428 /* Call the Media layer start function for left channel */
EricLew 0:3eee9435dd17 429 if(HAL_DFSDM_FilterRegularStart_DMA(&BSP_AUDIO_hDfsdmLeftFilter,
EricLew 0:3eee9435dd17 430 (int32_t*)hAudioIn.LeftRecBuff,
EricLew 0:3eee9435dd17 431 (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR)) != HAL_OK)
EricLew 0:3eee9435dd17 432 {
EricLew 0:3eee9435dd17 433 return AUDIO_ERROR;
EricLew 0:3eee9435dd17 434 }
EricLew 0:3eee9435dd17 435
EricLew 0:3eee9435dd17 436 return AUDIO_OK;
EricLew 0:3eee9435dd17 437 }
EricLew 0:3eee9435dd17 438
EricLew 0:3eee9435dd17 439 /**
EricLew 0:3eee9435dd17 440 * @brief Updates the audio frequency.
EricLew 0:3eee9435dd17 441 * @param AudioFreq: Audio frequency used to record the audio stream.
EricLew 0:3eee9435dd17 442 * @note This API should be called after the BSP_AUDIO_IN_Init() to adjust the
EricLew 0:3eee9435dd17 443 * audio frequency.
EricLew 0:3eee9435dd17 444 * @retval BSP AUDIO status
EricLew 0:3eee9435dd17 445 */
EricLew 0:3eee9435dd17 446 uint8_t BSP_AUDIO_IN_SetFrequency(uint32_t AudioFreq)
EricLew 0:3eee9435dd17 447 {
EricLew 0:3eee9435dd17 448 /* Configure the SAI PLL according to the requested audio frequency */
EricLew 0:3eee9435dd17 449 if (AUDIO_SAIPLLConfig(AudioFreq) != AUDIO_OK)
EricLew 0:3eee9435dd17 450 {
EricLew 0:3eee9435dd17 451 return AUDIO_ERROR;
EricLew 0:3eee9435dd17 452 }
EricLew 0:3eee9435dd17 453
EricLew 0:3eee9435dd17 454 /* De-initializes the Digital Filter for Sigma-Delta Modulators interface */
EricLew 0:3eee9435dd17 455 if(AUDIO_DFSDMx_DeInit() != AUDIO_OK)
EricLew 0:3eee9435dd17 456 {
EricLew 0:3eee9435dd17 457 return AUDIO_ERROR;
EricLew 0:3eee9435dd17 458 }
EricLew 0:3eee9435dd17 459
EricLew 0:3eee9435dd17 460 /* Initializes the Digital Filter for Sigma-Delta Modulators interface */
EricLew 0:3eee9435dd17 461 if(AUDIO_DFSDMx_Init(AudioFreq) != AUDIO_OK)
EricLew 0:3eee9435dd17 462 {
EricLew 0:3eee9435dd17 463 return AUDIO_ERROR;
EricLew 0:3eee9435dd17 464 }
EricLew 0:3eee9435dd17 465
EricLew 0:3eee9435dd17 466 return AUDIO_OK;
EricLew 0:3eee9435dd17 467 }
EricLew 0:3eee9435dd17 468
EricLew 0:3eee9435dd17 469 /**
EricLew 0:3eee9435dd17 470 * @brief Regular conversion complete callback.
EricLew 0:3eee9435dd17 471 * @note In interrupt mode, user has to read conversion value in this function
EricLew 0:3eee9435dd17 472 using HAL_DFSDM_FilterGetRegularValue.
EricLew 0:3eee9435dd17 473 * @param hdfsdm_filter : DFSDM filter handle.
EricLew 0:3eee9435dd17 474 * @retval None
EricLew 0:3eee9435dd17 475 */
EricLew 0:3eee9435dd17 476 void HAL_DFSDM_FilterRegConvCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
EricLew 0:3eee9435dd17 477 {
EricLew 0:3eee9435dd17 478 uint32_t index;
EricLew 0:3eee9435dd17 479 uint32_t recbufsize = (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR);
EricLew 0:3eee9435dd17 480
EricLew 0:3eee9435dd17 481 for(index = (recbufsize/2); index < recbufsize; index++)
EricLew 0:3eee9435dd17 482 {
EricLew 0:3eee9435dd17 483 hAudioIn.pRecBuf[index] = (uint16_t)(SaturaLH((hAudioIn.LeftRecBuff[index] >> 8), -32760, 32760));
EricLew 0:3eee9435dd17 484 }
EricLew 0:3eee9435dd17 485
EricLew 0:3eee9435dd17 486 /* Invoke the registered 'TransferComplete' function (if any) */
EricLew 0:3eee9435dd17 487 if (hAudioIn.CbTransferComplete != (Audio_CallbackTypeDef)NULL)
EricLew 0:3eee9435dd17 488 {
EricLew 0:3eee9435dd17 489 hAudioIn.CbTransferComplete();
EricLew 0:3eee9435dd17 490 }
EricLew 0:3eee9435dd17 491 }
EricLew 0:3eee9435dd17 492
EricLew 0:3eee9435dd17 493 /**
EricLew 0:3eee9435dd17 494 * @brief Half regular conversion complete callback.
EricLew 0:3eee9435dd17 495 * @param hdfsdm_filter : DFSDM filter handle.
EricLew 0:3eee9435dd17 496 * @retval None
EricLew 0:3eee9435dd17 497 */
EricLew 0:3eee9435dd17 498 void HAL_DFSDM_FilterRegConvHalfCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
EricLew 0:3eee9435dd17 499 {
EricLew 0:3eee9435dd17 500 uint32_t index;
EricLew 0:3eee9435dd17 501 uint32_t recbufsize = (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR);
EricLew 0:3eee9435dd17 502
EricLew 0:3eee9435dd17 503
EricLew 0:3eee9435dd17 504 for(index = 0; index < (recbufsize/2); index++)
EricLew 0:3eee9435dd17 505 {
EricLew 0:3eee9435dd17 506 hAudioIn.pRecBuf[index] = (uint16_t)(SaturaLH((hAudioIn.LeftRecBuff[index] >> 8), -32760, 32760));
EricLew 0:3eee9435dd17 507 }
EricLew 0:3eee9435dd17 508
EricLew 0:3eee9435dd17 509 /* Invoke the registered 'HalfTransfer' callback function (if any) */
EricLew 0:3eee9435dd17 510 if (hAudioIn.CbHalfTransfer != (Audio_CallbackTypeDef)NULL)
EricLew 0:3eee9435dd17 511 {
EricLew 0:3eee9435dd17 512 hAudioIn.CbHalfTransfer();
EricLew 0:3eee9435dd17 513 }
EricLew 0:3eee9435dd17 514 }
EricLew 0:3eee9435dd17 515
EricLew 0:3eee9435dd17 516 /**
EricLew 0:3eee9435dd17 517 * @brief Error callback.
EricLew 0:3eee9435dd17 518 * @param hdfsdm_filter : DFSDM filter handle.
EricLew 0:3eee9435dd17 519 * @retval None
EricLew 0:3eee9435dd17 520 */
EricLew 0:3eee9435dd17 521 void HAL_DFSDM_FilterErrorCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
EricLew 0:3eee9435dd17 522 {
EricLew 0:3eee9435dd17 523 /* Invoke the registered 'ErrorCallback' callback function (if any) */
EricLew 0:3eee9435dd17 524 if (hAudioIn.CbError != (Audio_CallbackTypeDef)NULL)
EricLew 0:3eee9435dd17 525 {
EricLew 0:3eee9435dd17 526 hAudioIn.CbError();
EricLew 0:3eee9435dd17 527 }
EricLew 0:3eee9435dd17 528 }
EricLew 0:3eee9435dd17 529
EricLew 0:3eee9435dd17 530 /**
EricLew 0:3eee9435dd17 531 * @brief Stops audio recording.
EricLew 0:3eee9435dd17 532 * @retval BSP AUDIO status
EricLew 0:3eee9435dd17 533 */
EricLew 0:3eee9435dd17 534 uint8_t BSP_AUDIO_IN_Stop(void)
EricLew 0:3eee9435dd17 535 {
EricLew 0:3eee9435dd17 536 /* Call the Media layer stop function for left channel */
EricLew 0:3eee9435dd17 537 if(HAL_DFSDM_FilterRegularStop_DMA(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK )
EricLew 0:3eee9435dd17 538 {
EricLew 0:3eee9435dd17 539 return AUDIO_ERROR;
EricLew 0:3eee9435dd17 540 }
EricLew 0:3eee9435dd17 541
EricLew 0:3eee9435dd17 542 /* Free hAudioIn.LeftRecBuff buffer */
EricLew 0:3eee9435dd17 543 #if defined(BSP_AUDIO_USE_RTOS)
EricLew 0:3eee9435dd17 544 k_free((void *)hAudioIn.LeftRecBuff);
EricLew 0:3eee9435dd17 545 #else
EricLew 0:3eee9435dd17 546 free((void *)hAudioIn.LeftRecBuff);
EricLew 0:3eee9435dd17 547 #endif
EricLew 0:3eee9435dd17 548
EricLew 0:3eee9435dd17 549 return AUDIO_OK;
EricLew 0:3eee9435dd17 550 }
EricLew 0:3eee9435dd17 551
EricLew 0:3eee9435dd17 552 /**
EricLew 0:3eee9435dd17 553 * @brief Pauses the audio file stream.
EricLew 0:3eee9435dd17 554 * @retval BSP AUDIO status
EricLew 0:3eee9435dd17 555 */
EricLew 0:3eee9435dd17 556 uint8_t BSP_AUDIO_IN_Pause(void)
EricLew 0:3eee9435dd17 557 {
EricLew 0:3eee9435dd17 558 /* Call the Media layer stop function */
EricLew 0:3eee9435dd17 559 if(HAL_DFSDM_FilterRegularStop_DMA(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK)
EricLew 0:3eee9435dd17 560 {
EricLew 0:3eee9435dd17 561 return AUDIO_ERROR;
EricLew 0:3eee9435dd17 562 }
EricLew 0:3eee9435dd17 563
EricLew 0:3eee9435dd17 564 return AUDIO_OK;
EricLew 0:3eee9435dd17 565 }
EricLew 0:3eee9435dd17 566
EricLew 0:3eee9435dd17 567 /**
EricLew 0:3eee9435dd17 568 * @brief Resumes the audio file stream.
EricLew 0:3eee9435dd17 569 * @retval BSP AUDIO status
EricLew 0:3eee9435dd17 570 */
EricLew 0:3eee9435dd17 571 uint8_t BSP_AUDIO_IN_Resume(void)
EricLew 0:3eee9435dd17 572 {
EricLew 0:3eee9435dd17 573 /* Call the Media layer start function for left channel */
EricLew 0:3eee9435dd17 574 if(HAL_DFSDM_FilterRegularStart_DMA(&BSP_AUDIO_hDfsdmLeftFilter,
EricLew 0:3eee9435dd17 575 (int32_t*)hAudioIn.LeftRecBuff,
EricLew 0:3eee9435dd17 576 (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR)) != HAL_OK)
EricLew 0:3eee9435dd17 577 {
EricLew 0:3eee9435dd17 578 return AUDIO_ERROR;
EricLew 0:3eee9435dd17 579 }
EricLew 0:3eee9435dd17 580
EricLew 0:3eee9435dd17 581 return AUDIO_OK;
EricLew 0:3eee9435dd17 582 }
EricLew 0:3eee9435dd17 583
EricLew 0:3eee9435dd17 584 /**
EricLew 0:3eee9435dd17 585 * @brief register user callback functions
EricLew 0:3eee9435dd17 586 * @param ErrorCallback: pointer to the error callback function
EricLew 0:3eee9435dd17 587 * @param HalfTransferCallback: pointer to the half transfer callback function
EricLew 0:3eee9435dd17 588 * @param TransferCompleteCallback: pointer to the transfer complete callback function
EricLew 0:3eee9435dd17 589 * @retval None
EricLew 0:3eee9435dd17 590 */
EricLew 0:3eee9435dd17 591 void BSP_AUDIO_IN_RegisterCallbacks(Audio_CallbackTypeDef ErrorCallback,
EricLew 0:3eee9435dd17 592 Audio_CallbackTypeDef HalfTransferCallback,
EricLew 0:3eee9435dd17 593 Audio_CallbackTypeDef TransferCompleteCallback)
EricLew 0:3eee9435dd17 594 {
EricLew 0:3eee9435dd17 595 hAudioIn.CbError = ErrorCallback;
EricLew 0:3eee9435dd17 596 hAudioIn.CbHalfTransfer = HalfTransferCallback;
EricLew 0:3eee9435dd17 597 hAudioIn.CbTransferComplete = TransferCompleteCallback;
EricLew 0:3eee9435dd17 598 }
EricLew 0:3eee9435dd17 599 /**
EricLew 0:3eee9435dd17 600 * @}
EricLew 0:3eee9435dd17 601 */
EricLew 0:3eee9435dd17 602
EricLew 0:3eee9435dd17 603 /* private functions --------------------------------------------------------*/
EricLew 0:3eee9435dd17 604 /** @addtogroup STM32L476G_DISCOVERY_AUDIO_Private_Functions
EricLew 0:3eee9435dd17 605 * @{
EricLew 0:3eee9435dd17 606 */
EricLew 0:3eee9435dd17 607 /**
EricLew 0:3eee9435dd17 608 * @brief Initializes the Audio Codec audio interface (SAI).
EricLew 0:3eee9435dd17 609 * @param AudioFreq: Audio frequency to be configured for the SAI peripheral.
EricLew 0:3eee9435dd17 610 * @note The default SlotActive configuration is set to CODEC_AUDIOFRAME_SLOT_0123
EricLew 0:3eee9435dd17 611 * and user can update this configuration using
EricLew 0:3eee9435dd17 612 * @retval BSP AUDIO status
EricLew 0:3eee9435dd17 613 */
EricLew 0:3eee9435dd17 614 static uint8_t AUDIO_SAIx_Init(uint32_t AudioFreq)
EricLew 0:3eee9435dd17 615 {
EricLew 0:3eee9435dd17 616 /* Disable SAI peripheral to allow access to SAI internal registers */
EricLew 0:3eee9435dd17 617 __HAL_SAI_DISABLE(&BSP_AUDIO_hSai);
EricLew 0:3eee9435dd17 618
EricLew 0:3eee9435dd17 619 /* Initialize the BSP_AUDIO_hSai Instance parameter */
EricLew 0:3eee9435dd17 620 BSP_AUDIO_hSai.Instance = AUDIO_SAIx;
EricLew 0:3eee9435dd17 621
EricLew 0:3eee9435dd17 622 /* Configure SAI_Block_x
EricLew 0:3eee9435dd17 623 LSBFirst: Disabled
EricLew 0:3eee9435dd17 624 DataSize: 16 */
EricLew 0:3eee9435dd17 625 BSP_AUDIO_hSai.Init.AudioMode = SAI_MODEMASTER_TX;
EricLew 0:3eee9435dd17 626 BSP_AUDIO_hSai.Init.Synchro = SAI_ASYNCHRONOUS;
EricLew 0:3eee9435dd17 627 BSP_AUDIO_hSai.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
EricLew 0:3eee9435dd17 628 BSP_AUDIO_hSai.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
EricLew 0:3eee9435dd17 629 BSP_AUDIO_hSai.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
EricLew 0:3eee9435dd17 630 BSP_AUDIO_hSai.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
EricLew 0:3eee9435dd17 631 BSP_AUDIO_hSai.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_MCKDIV;
EricLew 0:3eee9435dd17 632 BSP_AUDIO_hSai.Init.Mckdiv = SAIClockDivider(AudioFreq);
EricLew 0:3eee9435dd17 633 BSP_AUDIO_hSai.Init.MonoStereoMode = SAI_STEREOMODE;
EricLew 0:3eee9435dd17 634 BSP_AUDIO_hSai.Init.CompandingMode = SAI_NOCOMPANDING;
EricLew 0:3eee9435dd17 635 BSP_AUDIO_hSai.Init.TriState = SAI_OUTPUT_NOTRELEASED;
EricLew 0:3eee9435dd17 636 BSP_AUDIO_hSai.Init.Protocol = SAI_FREE_PROTOCOL;
EricLew 0:3eee9435dd17 637 BSP_AUDIO_hSai.Init.DataSize = SAI_DATASIZE_16;
EricLew 0:3eee9435dd17 638 BSP_AUDIO_hSai.Init.FirstBit = SAI_FIRSTBIT_MSB;
EricLew 0:3eee9435dd17 639 BSP_AUDIO_hSai.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
EricLew 0:3eee9435dd17 640
EricLew 0:3eee9435dd17 641 /* Configure SAI_Block_x Frame
EricLew 0:3eee9435dd17 642 Frame Length: 32
EricLew 0:3eee9435dd17 643 Frame active Length: 16
EricLew 0:3eee9435dd17 644 FS Definition: Start frame + Channel Side identification
EricLew 0:3eee9435dd17 645 FS Polarity: FS active Low
EricLew 0:3eee9435dd17 646 FS Offset: FS asserted one bit before the first bit of slot 0 */
EricLew 0:3eee9435dd17 647 BSP_AUDIO_hSai.FrameInit.FrameLength = 32;
EricLew 0:3eee9435dd17 648 BSP_AUDIO_hSai.FrameInit.ActiveFrameLength = 16;
EricLew 0:3eee9435dd17 649 BSP_AUDIO_hSai.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
EricLew 0:3eee9435dd17 650 BSP_AUDIO_hSai.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
EricLew 0:3eee9435dd17 651 BSP_AUDIO_hSai.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
EricLew 0:3eee9435dd17 652
EricLew 0:3eee9435dd17 653 /* Configure SAI Block_x Slot
EricLew 0:3eee9435dd17 654 Slot First Bit Offset: 0
EricLew 0:3eee9435dd17 655 Slot Size : 16
EricLew 0:3eee9435dd17 656 Slot Number: 2
EricLew 0:3eee9435dd17 657 Slot Active: Slots 0 and 1 actives */
EricLew 0:3eee9435dd17 658 BSP_AUDIO_hSai.SlotInit.FirstBitOffset = 0;
EricLew 0:3eee9435dd17 659 BSP_AUDIO_hSai.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
EricLew 0:3eee9435dd17 660 BSP_AUDIO_hSai.SlotInit.SlotNumber = 2;
EricLew 0:3eee9435dd17 661 BSP_AUDIO_hSai.SlotInit.SlotActive = SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1;
EricLew 0:3eee9435dd17 662
EricLew 0:3eee9435dd17 663 /* Initializes the SAI peripheral*/
EricLew 0:3eee9435dd17 664 if (HAL_SAI_Init(&BSP_AUDIO_hSai) != HAL_OK)
EricLew 0:3eee9435dd17 665 {
EricLew 0:3eee9435dd17 666 return AUDIO_ERROR;
EricLew 0:3eee9435dd17 667 }
EricLew 0:3eee9435dd17 668
EricLew 0:3eee9435dd17 669 /* Enable SAI peripheral to generate MCLK */
EricLew 0:3eee9435dd17 670 __HAL_SAI_ENABLE(&BSP_AUDIO_hSai);
EricLew 0:3eee9435dd17 671
EricLew 0:3eee9435dd17 672 return AUDIO_OK;
EricLew 0:3eee9435dd17 673
EricLew 0:3eee9435dd17 674 }
EricLew 0:3eee9435dd17 675
EricLew 0:3eee9435dd17 676 /**
EricLew 0:3eee9435dd17 677 * @brief De-initializes the Audio Codec audio interface (SAI).
EricLew 0:3eee9435dd17 678 * @retval BSP AUDIO status
EricLew 0:3eee9435dd17 679 */
EricLew 0:3eee9435dd17 680 static uint8_t AUDIO_SAIx_DeInit(void)
EricLew 0:3eee9435dd17 681 {
EricLew 0:3eee9435dd17 682 /* Disable the SAI audio block */
EricLew 0:3eee9435dd17 683 __HAL_SAI_DISABLE(&BSP_AUDIO_hSai);
EricLew 0:3eee9435dd17 684
EricLew 0:3eee9435dd17 685 /* De-initializes the SAI peripheral */
EricLew 0:3eee9435dd17 686 if (HAL_SAI_DeInit(&BSP_AUDIO_hSai) != HAL_OK)
EricLew 0:3eee9435dd17 687 {
EricLew 0:3eee9435dd17 688 return AUDIO_ERROR;
EricLew 0:3eee9435dd17 689 }
EricLew 0:3eee9435dd17 690
EricLew 0:3eee9435dd17 691 /* Disable SAIx PLL */
EricLew 0:3eee9435dd17 692 if (AUDIO_SAIx_PLL_DISABLE() != AUDIO_OK)
EricLew 0:3eee9435dd17 693 {
EricLew 0:3eee9435dd17 694 return AUDIO_ERROR;
EricLew 0:3eee9435dd17 695 }
EricLew 0:3eee9435dd17 696
EricLew 0:3eee9435dd17 697 return AUDIO_OK;
EricLew 0:3eee9435dd17 698 }
EricLew 0:3eee9435dd17 699
EricLew 0:3eee9435dd17 700 /**
EricLew 0:3eee9435dd17 701 * @brief SAI MSP Init
EricLew 0:3eee9435dd17 702 * @param hsai : pointer to a SAI_HandleTypeDef structure
EricLew 0:3eee9435dd17 703 * @retval None
EricLew 0:3eee9435dd17 704 */
EricLew 0:3eee9435dd17 705 void HAL_SAI_MspInit(SAI_HandleTypeDef *hsai)
EricLew 0:3eee9435dd17 706 {
EricLew 0:3eee9435dd17 707 GPIO_InitTypeDef GPIO_InitStruct;
EricLew 0:3eee9435dd17 708
EricLew 0:3eee9435dd17 709 /* Enable SAI clock */
EricLew 0:3eee9435dd17 710 AUDIO_SAIx_CLK_ENABLE();
EricLew 0:3eee9435dd17 711
EricLew 0:3eee9435dd17 712 /* Enable GPIO clock */
EricLew 0:3eee9435dd17 713 AUDIO_SAIx_MCK_SCK_SD_FS_ENABLE();
EricLew 0:3eee9435dd17 714
EricLew 0:3eee9435dd17 715 /* CODEC_SAI pins configuration: FS, SCK, MCK and SD pins ------------------*/
EricLew 0:3eee9435dd17 716 GPIO_InitStruct.Pin = AUDIO_SAIx_FS_PIN | AUDIO_SAIx_SCK_PIN | AUDIO_SAIx_SD_PIN | AUDIO_SAIx_MCK_PIN;
EricLew 0:3eee9435dd17 717 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
EricLew 0:3eee9435dd17 718 GPIO_InitStruct.Pull = GPIO_NOPULL;
EricLew 0:3eee9435dd17 719 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
EricLew 0:3eee9435dd17 720 GPIO_InitStruct.Alternate = AUDIO_SAIx_MCK_SCK_SD_FS_AF;
EricLew 0:3eee9435dd17 721 HAL_GPIO_Init(AUDIO_SAIx_MCK_SCK_SD_FS_GPIO_PORT, &GPIO_InitStruct);
EricLew 0:3eee9435dd17 722
EricLew 0:3eee9435dd17 723 /* Enable the DMA clock */
EricLew 0:3eee9435dd17 724 AUDIO_SAIx_DMAx_CLK_ENABLE();
EricLew 0:3eee9435dd17 725
EricLew 0:3eee9435dd17 726 if(hsai->Instance == AUDIO_SAIx)
EricLew 0:3eee9435dd17 727 {
EricLew 0:3eee9435dd17 728 /* Configure the hDmaSai handle parameters */
EricLew 0:3eee9435dd17 729 hDmaSai.Init.Request = DMA_REQUEST_1;
EricLew 0:3eee9435dd17 730 hDmaSai.Init.Direction = DMA_MEMORY_TO_PERIPH;
EricLew 0:3eee9435dd17 731 hDmaSai.Init.PeriphInc = DMA_PINC_DISABLE;
EricLew 0:3eee9435dd17 732 hDmaSai.Init.MemInc = DMA_MINC_ENABLE;
EricLew 0:3eee9435dd17 733 hDmaSai.Init.PeriphDataAlignment = AUDIO_SAIx_DMAx_PERIPH_DATA_SIZE;
EricLew 0:3eee9435dd17 734 hDmaSai.Init.MemDataAlignment = AUDIO_SAIx_DMAx_MEM_DATA_SIZE;
EricLew 0:3eee9435dd17 735 hDmaSai.Init.Mode = DMA_NORMAL;
EricLew 0:3eee9435dd17 736 hDmaSai.Init.Priority = DMA_PRIORITY_HIGH;
EricLew 0:3eee9435dd17 737
EricLew 0:3eee9435dd17 738 hDmaSai.Instance = AUDIO_SAIx_DMAx_CHANNEL;
EricLew 0:3eee9435dd17 739
EricLew 0:3eee9435dd17 740 /* Associate the DMA handle */
EricLew 0:3eee9435dd17 741 __HAL_LINKDMA(hsai, hdmatx, hDmaSai);
EricLew 0:3eee9435dd17 742
EricLew 0:3eee9435dd17 743 /* Deinitialize the Stream for new transfer */
EricLew 0:3eee9435dd17 744 HAL_DMA_DeInit(&hDmaSai);
EricLew 0:3eee9435dd17 745
EricLew 0:3eee9435dd17 746 /* Configure the DMA Stream */
EricLew 0:3eee9435dd17 747 HAL_DMA_Init(&hDmaSai);
EricLew 0:3eee9435dd17 748 }
EricLew 0:3eee9435dd17 749
EricLew 0:3eee9435dd17 750 /* SAI DMA IRQ Channel configuration */
EricLew 0:3eee9435dd17 751 HAL_NVIC_SetPriority(AUDIO_SAIx_DMAx_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0);
EricLew 0:3eee9435dd17 752 HAL_NVIC_EnableIRQ(AUDIO_SAIx_DMAx_IRQ);
EricLew 0:3eee9435dd17 753 }
EricLew 0:3eee9435dd17 754
EricLew 0:3eee9435dd17 755 /**
EricLew 0:3eee9435dd17 756 * @brief SAI MSP De-init
EricLew 0:3eee9435dd17 757 * @param hsai : pointer to a SAI_HandleTypeDef structure
EricLew 0:3eee9435dd17 758 * @retval None
EricLew 0:3eee9435dd17 759 */
EricLew 0:3eee9435dd17 760 void HAL_SAI_MspDeInit(SAI_HandleTypeDef *hsai)
EricLew 0:3eee9435dd17 761 {
EricLew 0:3eee9435dd17 762 /* Disable SAI DMA Channel IRQ */
EricLew 0:3eee9435dd17 763 HAL_NVIC_DisableIRQ(AUDIO_SAIx_DMAx_IRQ);
EricLew 0:3eee9435dd17 764
EricLew 0:3eee9435dd17 765 /* Reset the DMA Stream configuration*/
EricLew 0:3eee9435dd17 766 HAL_DMA_DeInit(&hDmaSai);
EricLew 0:3eee9435dd17 767
EricLew 0:3eee9435dd17 768 /* Disable the DMA clock */
EricLew 0:3eee9435dd17 769 AUDIO_SAIx_DMAx_CLK_DISABLE();
EricLew 0:3eee9435dd17 770
EricLew 0:3eee9435dd17 771 /* De-initialize FS, SCK, MCK and SD pins*/
EricLew 0:3eee9435dd17 772 HAL_GPIO_DeInit(AUDIO_SAIx_MCK_SCK_SD_FS_GPIO_PORT,
EricLew 0:3eee9435dd17 773 AUDIO_SAIx_FS_PIN | AUDIO_SAIx_SCK_PIN | AUDIO_SAIx_SD_PIN | AUDIO_SAIx_MCK_PIN);
EricLew 0:3eee9435dd17 774
EricLew 0:3eee9435dd17 775 /* Disable GPIO clock */
EricLew 0:3eee9435dd17 776 AUDIO_SAIx_MCK_SCK_SD_FS_DISABLE();
EricLew 0:3eee9435dd17 777
EricLew 0:3eee9435dd17 778 /* Disable SAI clock */
EricLew 0:3eee9435dd17 779 AUDIO_SAIx_CLK_DISABLE();
EricLew 0:3eee9435dd17 780 }
EricLew 0:3eee9435dd17 781
EricLew 0:3eee9435dd17 782 /**
EricLew 0:3eee9435dd17 783 * @brief Resets the audio codec. It restores the default configuration of the
EricLew 0:3eee9435dd17 784 * codec (this function shall be called before initializing the codec).
EricLew 0:3eee9435dd17 785 * @retval None
EricLew 0:3eee9435dd17 786 */
EricLew 0:3eee9435dd17 787
EricLew 0:3eee9435dd17 788
EricLew 0:3eee9435dd17 789 /**
EricLew 0:3eee9435dd17 790 * @}
EricLew 0:3eee9435dd17 791 */
EricLew 0:3eee9435dd17 792
EricLew 0:3eee9435dd17 793 /** @addtogroup STM32L476G_DISCOVERY_AUDIO_Private_Functions
EricLew 0:3eee9435dd17 794 * @{
EricLew 0:3eee9435dd17 795 */
EricLew 0:3eee9435dd17 796
EricLew 0:3eee9435dd17 797 /**
EricLew 0:3eee9435dd17 798 * @brief Initializes the Digital Filter for Sigma-Delta Modulators interface (DFSDM).
EricLew 0:3eee9435dd17 799 * @param AudioFreq: Audio frequency to be used to set correctly the DFSDM peripheral.
EricLew 0:3eee9435dd17 800 * @retval BSP AUDIO status
EricLew 0:3eee9435dd17 801 */
EricLew 0:3eee9435dd17 802 static uint8_t AUDIO_DFSDMx_Init(uint32_t AudioFreq)
EricLew 0:3eee9435dd17 803 {
EricLew 0:3eee9435dd17 804 /*####CHANNEL 2####*/
EricLew 0:3eee9435dd17 805 hAudioIn.hDfsdmLeftChannel.Init.OutputClock.Activation = ENABLE;
EricLew 0:3eee9435dd17 806 hAudioIn.hDfsdmLeftChannel.Init.OutputClock.Selection = DFSDM_CHANNEL_OUTPUT_CLOCK_AUDIO;
EricLew 0:3eee9435dd17 807 /* Set the DFSDM clock OUT audio frequency configuration */
EricLew 0:3eee9435dd17 808 hAudioIn.hDfsdmLeftChannel.Init.OutputClock.Divider = DFSDMClockDivider(AudioFreq);
EricLew 0:3eee9435dd17 809 hAudioIn.hDfsdmLeftChannel.Init.Input.Multiplexer = DFSDM_CHANNEL_EXTERNAL_INPUTS;
EricLew 0:3eee9435dd17 810 hAudioIn.hDfsdmLeftChannel.Init.Input.DataPacking = DFSDM_CHANNEL_STANDARD_MODE;
EricLew 0:3eee9435dd17 811 hAudioIn.hDfsdmLeftChannel.Init.Input.Pins = DFSDM_CHANNEL_SAME_CHANNEL_PINS;
EricLew 0:3eee9435dd17 812 /* Request to sample stable data for LEFT micro on Rising edge */
EricLew 0:3eee9435dd17 813 hAudioIn.hDfsdmLeftChannel.Init.SerialInterface.Type = DFSDM_CHANNEL_SPI_RISING;
EricLew 0:3eee9435dd17 814 hAudioIn.hDfsdmLeftChannel.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
EricLew 0:3eee9435dd17 815 hAudioIn.hDfsdmLeftChannel.Init.Awd.FilterOrder = DFSDM_CHANNEL_SINC1_ORDER;
EricLew 0:3eee9435dd17 816 hAudioIn.hDfsdmLeftChannel.Init.Awd.Oversampling = 10;
EricLew 0:3eee9435dd17 817 hAudioIn.hDfsdmLeftChannel.Init.Offset = 0;
EricLew 0:3eee9435dd17 818 hAudioIn.hDfsdmLeftChannel.Init.RightBitShift = DFSDMRightBitShift(AudioFreq);
EricLew 0:3eee9435dd17 819
EricLew 0:3eee9435dd17 820 hAudioIn.hDfsdmLeftChannel.Instance = DFSDM_Channel2;
EricLew 0:3eee9435dd17 821
EricLew 0:3eee9435dd17 822 /* Init the DFSDM Channel */
EricLew 0:3eee9435dd17 823 if (HAL_DFSDM_ChannelInit(&hAudioIn.hDfsdmLeftChannel) != HAL_OK)
EricLew 0:3eee9435dd17 824 {
EricLew 0:3eee9435dd17 825 return AUDIO_ERROR;
EricLew 0:3eee9435dd17 826 }
EricLew 0:3eee9435dd17 827
EricLew 0:3eee9435dd17 828 /*####FILTER 0####*/
EricLew 0:3eee9435dd17 829 BSP_AUDIO_hDfsdmLeftFilter.Init.RegularParam.Trigger = DFSDM_FILTER_SW_TRIGGER;
EricLew 0:3eee9435dd17 830 BSP_AUDIO_hDfsdmLeftFilter.Init.RegularParam.FastMode = ENABLE;
EricLew 0:3eee9435dd17 831 BSP_AUDIO_hDfsdmLeftFilter.Init.RegularParam.DmaMode = ENABLE;
EricLew 0:3eee9435dd17 832 BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.Trigger = DFSDM_FILTER_SW_TRIGGER;
EricLew 0:3eee9435dd17 833 BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.ScanMode = DISABLE;
EricLew 0:3eee9435dd17 834 BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.DmaMode = DISABLE;
EricLew 0:3eee9435dd17 835 BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.ExtTrigger = DFSDM_FILTER_EXT_TRIG_TIM8_TRGO;
EricLew 0:3eee9435dd17 836 BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.ExtTriggerEdge = DFSDM_FILTER_EXT_TRIG_BOTH_EDGES;
EricLew 0:3eee9435dd17 837 BSP_AUDIO_hDfsdmLeftFilter.Init.FilterParam.SincOrder = DFSDMFilterOrder(AudioFreq);
EricLew 0:3eee9435dd17 838 /* Set the DFSDM Filters Oversampling to have correct sample rate */
EricLew 0:3eee9435dd17 839 BSP_AUDIO_hDfsdmLeftFilter.Init.FilterParam.Oversampling = DFSDMOverSampling(AudioFreq);
EricLew 0:3eee9435dd17 840 BSP_AUDIO_hDfsdmLeftFilter.Init.FilterParam.IntOversampling = 1;
EricLew 0:3eee9435dd17 841
EricLew 0:3eee9435dd17 842 BSP_AUDIO_hDfsdmLeftFilter.Instance = AUDIO_DFSDMx_LEFT_FILTER;
EricLew 0:3eee9435dd17 843
EricLew 0:3eee9435dd17 844 /* Init the DFSDM Filter */
EricLew 0:3eee9435dd17 845 if (HAL_DFSDM_FilterInit(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK)
EricLew 0:3eee9435dd17 846 {
EricLew 0:3eee9435dd17 847 return AUDIO_ERROR;
EricLew 0:3eee9435dd17 848 }
EricLew 0:3eee9435dd17 849
EricLew 0:3eee9435dd17 850 /* Configure regular channel */
EricLew 0:3eee9435dd17 851 if (HAL_DFSDM_FilterConfigRegChannel(&BSP_AUDIO_hDfsdmLeftFilter,
EricLew 0:3eee9435dd17 852 DFSDM_CHANNEL_2,
EricLew 0:3eee9435dd17 853 DFSDM_CONTINUOUS_CONV_ON) != HAL_OK)
EricLew 0:3eee9435dd17 854 {
EricLew 0:3eee9435dd17 855 return AUDIO_ERROR;
EricLew 0:3eee9435dd17 856 }
EricLew 0:3eee9435dd17 857
EricLew 0:3eee9435dd17 858 return AUDIO_OK;
EricLew 0:3eee9435dd17 859 }
EricLew 0:3eee9435dd17 860
EricLew 0:3eee9435dd17 861 /**
EricLew 0:3eee9435dd17 862 * @brief De-initializes the Digital Filter for Sigma-Delta Modulators interface (DFSDM).
EricLew 0:3eee9435dd17 863 * @retval BSP AUDIO status
EricLew 0:3eee9435dd17 864 */
EricLew 0:3eee9435dd17 865 static uint8_t AUDIO_DFSDMx_DeInit(void)
EricLew 0:3eee9435dd17 866 {
EricLew 0:3eee9435dd17 867 /* De-initializes the DFSDM filters to allow access to DFSDM internal registers */
EricLew 0:3eee9435dd17 868 if (HAL_DFSDM_FilterDeInit(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK)
EricLew 0:3eee9435dd17 869 {
EricLew 0:3eee9435dd17 870 return AUDIO_ERROR;
EricLew 0:3eee9435dd17 871 }
EricLew 0:3eee9435dd17 872
EricLew 0:3eee9435dd17 873 /* De-initializes the DFSDM channels to allow access to DFSDM internal registers */
EricLew 0:3eee9435dd17 874 if (HAL_DFSDM_ChannelDeInit(&hAudioIn.hDfsdmLeftChannel) != HAL_OK)
EricLew 0:3eee9435dd17 875 {
EricLew 0:3eee9435dd17 876 return AUDIO_ERROR;
EricLew 0:3eee9435dd17 877 }
EricLew 0:3eee9435dd17 878
EricLew 0:3eee9435dd17 879 /* Disable DFSDM clock */
EricLew 0:3eee9435dd17 880 AUDIO_DFSDMx_CLK_DISABLE();
EricLew 0:3eee9435dd17 881
EricLew 0:3eee9435dd17 882 /* Disable SAIx PLL */
EricLew 0:3eee9435dd17 883 if (AUDIO_SAIx_PLL_DISABLE() != AUDIO_OK)
EricLew 0:3eee9435dd17 884 {
EricLew 0:3eee9435dd17 885 return AUDIO_ERROR;
EricLew 0:3eee9435dd17 886 }
EricLew 0:3eee9435dd17 887
EricLew 0:3eee9435dd17 888 /* DFSDM reset */
EricLew 0:3eee9435dd17 889 __HAL_RCC_DFSDM_FORCE_RESET();
EricLew 0:3eee9435dd17 890 __HAL_RCC_DFSDM_RELEASE_RESET();
EricLew 0:3eee9435dd17 891
EricLew 0:3eee9435dd17 892 return AUDIO_OK;
EricLew 0:3eee9435dd17 893 }
EricLew 0:3eee9435dd17 894
EricLew 0:3eee9435dd17 895 /**
EricLew 0:3eee9435dd17 896 * @brief Initializes the DFSDM channel MSP.
EricLew 0:3eee9435dd17 897 * @param hdfsdm_channel : DFSDM channel handle.
EricLew 0:3eee9435dd17 898 * @retval None
EricLew 0:3eee9435dd17 899 */
EricLew 0:3eee9435dd17 900 void HAL_DFSDM_ChannelMspInit(DFSDM_Channel_HandleTypeDef *hdfsdm_channel)
EricLew 0:3eee9435dd17 901 {
EricLew 0:3eee9435dd17 902 GPIO_InitTypeDef GPIO_InitStruct;
EricLew 0:3eee9435dd17 903
EricLew 0:3eee9435dd17 904 /* Enable DFSDM clock */
EricLew 0:3eee9435dd17 905 AUDIO_DFSDMx_CLK_ENABLE();
EricLew 0:3eee9435dd17 906
EricLew 0:3eee9435dd17 907 /* Enable GPIO clock */
EricLew 0:3eee9435dd17 908 AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_CLK_ENABLE();
EricLew 0:3eee9435dd17 909
EricLew 0:3eee9435dd17 910 /* DFSDM pins configuration: DFSDM_CKOUT, DMIC_DATIN pins ------------------*/
EricLew 0:3eee9435dd17 911 GPIO_InitStruct.Pin = AUDIO_DFSDMx_CKOUT_PIN | AUDIO_DFSDMx_DMIC_DATIN_PIN;
EricLew 0:3eee9435dd17 912 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
EricLew 0:3eee9435dd17 913 GPIO_InitStruct.Pull = GPIO_NOPULL;
EricLew 0:3eee9435dd17 914 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
EricLew 0:3eee9435dd17 915 GPIO_InitStruct.Alternate = AUDIO_DFSDMx_CKOUT_DMIC_DATIN_AF;
EricLew 0:3eee9435dd17 916 HAL_GPIO_Init(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, &GPIO_InitStruct);
EricLew 0:3eee9435dd17 917 }
EricLew 0:3eee9435dd17 918
EricLew 0:3eee9435dd17 919 /**
EricLew 0:3eee9435dd17 920 * @brief De-initializes the DFSDM channel MSP.
EricLew 0:3eee9435dd17 921 * @param hdfsdm_channel : DFSDM channel handle.
EricLew 0:3eee9435dd17 922 * @retval None
EricLew 0:3eee9435dd17 923 */
EricLew 0:3eee9435dd17 924 void HAL_DFSDM_ChannelMspDeInit(DFSDM_Channel_HandleTypeDef *hdfsdm_channel)
EricLew 0:3eee9435dd17 925 {
EricLew 0:3eee9435dd17 926 GPIO_InitTypeDef GPIO_InitStruct;
EricLew 0:3eee9435dd17 927
EricLew 0:3eee9435dd17 928 /* Enable GPIO clock */
EricLew 0:3eee9435dd17 929 AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_CLK_ENABLE();
EricLew 0:3eee9435dd17 930
EricLew 0:3eee9435dd17 931 /* DFSDM pins configuration: DFSDM_CKOUT */
EricLew 0:3eee9435dd17 932 GPIO_InitStruct.Pin = AUDIO_DFSDMx_CKOUT_PIN;
EricLew 0:3eee9435dd17 933 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
EricLew 0:3eee9435dd17 934 GPIO_InitStruct.Pull = GPIO_NOPULL;
EricLew 0:3eee9435dd17 935 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
EricLew 0:3eee9435dd17 936 HAL_GPIO_Init(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, &GPIO_InitStruct);
EricLew 0:3eee9435dd17 937 HAL_GPIO_WritePin(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, AUDIO_DFSDMx_CKOUT_PIN, GPIO_PIN_RESET);
EricLew 0:3eee9435dd17 938
EricLew 0:3eee9435dd17 939
EricLew 0:3eee9435dd17 940 /* De-initialize DMIC_DATIN pin */
EricLew 0:3eee9435dd17 941 HAL_GPIO_DeInit(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, AUDIO_DFSDMx_DMIC_DATIN_PIN);
EricLew 0:3eee9435dd17 942 }
EricLew 0:3eee9435dd17 943
EricLew 0:3eee9435dd17 944 /**
EricLew 0:3eee9435dd17 945 * @brief Initializes the DFSDM filter MSP.
EricLew 0:3eee9435dd17 946 * @param hdfsdm_filter : DFSDM filter handle.
EricLew 0:3eee9435dd17 947 * @retval None
EricLew 0:3eee9435dd17 948 */
EricLew 0:3eee9435dd17 949 void HAL_DFSDM_FilterMspInit(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
EricLew 0:3eee9435dd17 950 {
EricLew 0:3eee9435dd17 951 /* Enable DFSDM clock */
EricLew 0:3eee9435dd17 952 AUDIO_DFSDMx_CLK_ENABLE();
EricLew 0:3eee9435dd17 953
EricLew 0:3eee9435dd17 954 /* Enable the DMA clock */
EricLew 0:3eee9435dd17 955 AUDIO_DFSDMx_DMAx_CLK_ENABLE();
EricLew 0:3eee9435dd17 956
EricLew 0:3eee9435dd17 957 /* Configure the hAudioIn.hDmaDfsdmLeft handle parameters */
EricLew 0:3eee9435dd17 958 hAudioIn.hDmaDfsdmLeft.Init.Request = DMA_REQUEST_0;
EricLew 0:3eee9435dd17 959 hAudioIn.hDmaDfsdmLeft.Init.Direction = DMA_PERIPH_TO_MEMORY;
EricLew 0:3eee9435dd17 960 hAudioIn.hDmaDfsdmLeft.Init.PeriphInc = DMA_PINC_DISABLE;
EricLew 0:3eee9435dd17 961 hAudioIn.hDmaDfsdmLeft.Init.MemInc = DMA_MINC_ENABLE;
EricLew 0:3eee9435dd17 962 hAudioIn.hDmaDfsdmLeft.Init.PeriphDataAlignment = AUDIO_DFSDMx_DMAx_PERIPH_DATA_SIZE;
EricLew 0:3eee9435dd17 963 hAudioIn.hDmaDfsdmLeft.Init.MemDataAlignment = AUDIO_DFSDMx_DMAx_MEM_DATA_SIZE;
EricLew 0:3eee9435dd17 964 hAudioIn.hDmaDfsdmLeft.Init.Mode = DMA_CIRCULAR;
EricLew 0:3eee9435dd17 965 hAudioIn.hDmaDfsdmLeft.Init.Priority = DMA_PRIORITY_HIGH;
EricLew 0:3eee9435dd17 966
EricLew 0:3eee9435dd17 967 hAudioIn.hDmaDfsdmLeft.Instance = AUDIO_DFSDMx_DMAx_LEFT_CHANNEL;
EricLew 0:3eee9435dd17 968
EricLew 0:3eee9435dd17 969 /* Associate the DMA handle */
EricLew 0:3eee9435dd17 970 __HAL_LINKDMA(hdfsdm_filter, hdmaReg, hAudioIn.hDmaDfsdmLeft);
EricLew 0:3eee9435dd17 971
EricLew 0:3eee9435dd17 972 /* Reset DMA handle state */
EricLew 0:3eee9435dd17 973 __HAL_DMA_RESET_HANDLE_STATE(&hAudioIn.hDmaDfsdmLeft);
EricLew 0:3eee9435dd17 974
EricLew 0:3eee9435dd17 975 /* Configure the DMA Channel */
EricLew 0:3eee9435dd17 976 HAL_DMA_Init(&hAudioIn.hDmaDfsdmLeft);
EricLew 0:3eee9435dd17 977
EricLew 0:3eee9435dd17 978 /* DMA IRQ Channel configuration */
EricLew 0:3eee9435dd17 979 HAL_NVIC_SetPriority(AUDIO_DFSDMx_DMAx_LEFT_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0);
EricLew 0:3eee9435dd17 980 HAL_NVIC_EnableIRQ(AUDIO_DFSDMx_DMAx_LEFT_IRQ);
EricLew 0:3eee9435dd17 981 }
EricLew 0:3eee9435dd17 982
EricLew 0:3eee9435dd17 983 /**
EricLew 0:3eee9435dd17 984 * @brief De-initializes the DFSDM filter MSP.
EricLew 0:3eee9435dd17 985 * @param hdfsdm_filter : DFSDM filter handle.
EricLew 0:3eee9435dd17 986 * @retval None
EricLew 0:3eee9435dd17 987 */
EricLew 0:3eee9435dd17 988 void HAL_DFSDM_FilterMspDeInit(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
EricLew 0:3eee9435dd17 989 {
EricLew 0:3eee9435dd17 990 /* Disable DMA Channel IRQ */
EricLew 0:3eee9435dd17 991 HAL_NVIC_DisableIRQ(AUDIO_DFSDMx_DMAx_LEFT_IRQ);
EricLew 0:3eee9435dd17 992
EricLew 0:3eee9435dd17 993 /* De-initialize the DMA Channel */
EricLew 0:3eee9435dd17 994 HAL_DMA_DeInit(&hAudioIn.hDmaDfsdmLeft);
EricLew 0:3eee9435dd17 995
EricLew 0:3eee9435dd17 996 /* Disable the DMA clock */
EricLew 0:3eee9435dd17 997 AUDIO_DFSDMx_DMAx_CLK_DISABLE();
EricLew 0:3eee9435dd17 998 }
EricLew 0:3eee9435dd17 999
EricLew 0:3eee9435dd17 1000 /**
EricLew 0:3eee9435dd17 1001 * @brief Configures the SAI PLL clock according to the required audio frequency.
EricLew 0:3eee9435dd17 1002 * @param Frequency: Audio frequency.
EricLew 0:3eee9435dd17 1003 * @retval BSP AUDIO status
EricLew 0:3eee9435dd17 1004 * @note The SAI PLL input clock must be configured in the user application.
EricLew 0:3eee9435dd17 1005 * The SAI PLL configuration done within this function assumes that
EricLew 0:3eee9435dd17 1006 * the SAI PLL input clock runs at 8 MHz.
EricLew 0:3eee9435dd17 1007 */
EricLew 0:3eee9435dd17 1008 static uint8_t AUDIO_SAIPLLConfig(uint32_t Frequency)
EricLew 0:3eee9435dd17 1009 {
EricLew 0:3eee9435dd17 1010 RCC_PeriphCLKInitTypeDef RCC_ExCLKInitStruct;
EricLew 0:3eee9435dd17 1011
EricLew 0:3eee9435dd17 1012 /* Retreive actual RCC configuration */
EricLew 0:3eee9435dd17 1013 HAL_RCCEx_GetPeriphCLKConfig(&RCC_ExCLKInitStruct);
EricLew 0:3eee9435dd17 1014
EricLew 0:3eee9435dd17 1015 if ( (Frequency == AUDIO_FREQUENCY_11K)
EricLew 0:3eee9435dd17 1016 || (Frequency == AUDIO_FREQUENCY_22K)
EricLew 0:3eee9435dd17 1017 || (Frequency == AUDIO_FREQUENCY_44K) )
EricLew 0:3eee9435dd17 1018 {
EricLew 0:3eee9435dd17 1019 /* Configure PLLSAI prescalers */
EricLew 0:3eee9435dd17 1020 /* SAI clock config
EricLew 0:3eee9435dd17 1021 PLLSAI1_VCO= 8 Mhz * PLLSAI1N = 8 * 24 = VCO_192M
EricLew 0:3eee9435dd17 1022 SAI_CK_x = PLLSAI1_VCO/PLLSAI1P = 192/17 = 11.294 Mhz */
EricLew 0:3eee9435dd17 1023 RCC_ExCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
EricLew 0:3eee9435dd17 1024 RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1N = 24;
EricLew 0:3eee9435dd17 1025 RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1P = 17;
EricLew 0:3eee9435dd17 1026 RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK;
EricLew 0:3eee9435dd17 1027 RCC_ExCLKInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI1;
EricLew 0:3eee9435dd17 1028 }
EricLew 0:3eee9435dd17 1029 else /* AUDIO_FREQUENCY_8K, AUDIO_FREQUENCY_16K, AUDIO_FREQUENCY_48K, AUDIO_FREQUENCY_96K */
EricLew 0:3eee9435dd17 1030 {
EricLew 0:3eee9435dd17 1031 /* SAI clock config
EricLew 0:3eee9435dd17 1032 PLLSAI1_VCO= 8 Mhz * PLLSAI1N = 8 * 43 = VCO_344M
EricLew 0:3eee9435dd17 1033 SAI_CK_x = PLLSAI1_VCO/PLLSAI1P = 344/7 = 49.142 Mhz */
EricLew 0:3eee9435dd17 1034 RCC_ExCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
EricLew 0:3eee9435dd17 1035 RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1N = 43;
EricLew 0:3eee9435dd17 1036 RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1P = 7;
EricLew 0:3eee9435dd17 1037 RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK;
EricLew 0:3eee9435dd17 1038 RCC_ExCLKInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI1;
EricLew 0:3eee9435dd17 1039 }
EricLew 0:3eee9435dd17 1040
EricLew 0:3eee9435dd17 1041 if (HAL_RCCEx_PeriphCLKConfig(&RCC_ExCLKInitStruct) != HAL_OK)
EricLew 0:3eee9435dd17 1042 {
EricLew 0:3eee9435dd17 1043 return AUDIO_ERROR;
EricLew 0:3eee9435dd17 1044 }
EricLew 0:3eee9435dd17 1045
EricLew 0:3eee9435dd17 1046 return AUDIO_OK;
EricLew 0:3eee9435dd17 1047 }
EricLew 0:3eee9435dd17 1048
EricLew 0:3eee9435dd17 1049 /**
EricLew 0:3eee9435dd17 1050 * @}
EricLew 0:3eee9435dd17 1051 */
EricLew 0:3eee9435dd17 1052
EricLew 0:3eee9435dd17 1053 /**
EricLew 0:3eee9435dd17 1054 * @}
EricLew 0:3eee9435dd17 1055 */
EricLew 0:3eee9435dd17 1056
EricLew 0:3eee9435dd17 1057 /**
EricLew 0:3eee9435dd17 1058 * @}
EricLew 0:3eee9435dd17 1059 */
EricLew 0:3eee9435dd17 1060
EricLew 0:3eee9435dd17 1061 /**
EricLew 0:3eee9435dd17 1062 * @}
EricLew 0:3eee9435dd17 1063 */
EricLew 0:3eee9435dd17 1064
EricLew 0:3eee9435dd17 1065 /**
EricLew 0:3eee9435dd17 1066 * @}
EricLew 0:3eee9435dd17 1067 */
EricLew 0:3eee9435dd17 1068
EricLew 0:3eee9435dd17 1069 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
EricLew 0:3eee9435dd17 1070
EricLew 0:3eee9435dd17 1071