Team Riedel - display

Dependencies:   LCD_fonts SPI_TFT_ILI9341 CMSIS_DSP_401_without_cm4 mbed-src SDFileSystem wavfile

Committer:
EricLew
Date:
Sun Dec 13 16:46:14 2015 +0000
Revision:
9:5a860b9c8a6a
Child:
10:0986108f8aa3
Added DFSDM core functionality

Who changed what in which revision?

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