Team Riedel - display

Dependencies:   LCD_fonts SPI_TFT_ILI9341 CMSIS_DSP_401_without_cm4 mbed-src SDFileSystem wavfile

Committer:
linx0576
Date:
Mon Dec 14 22:13:11 2015 +0000
Revision:
13:ab0285338951
Parent:
10:0986108f8aa3
update

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 {
linx0576 10:0986108f8aa3 429
EricLew 9:5a860b9c8a6a 430 hAudioIn.pRecBuf = pbuf;
EricLew 9:5a860b9c8a6a 431 hAudioIn.RecSize = size;
EricLew 9:5a860b9c8a6a 432
EricLew 9:5a860b9c8a6a 433 /* Allocate hAudioIn.LeftRecBuff buffer */
EricLew 9:5a860b9c8a6a 434 #if defined(BSP_AUDIO_USE_RTOS)
EricLew 9:5a860b9c8a6a 435 hAudioIn.LeftRecBuff = (int32_t *)k_malloc(size * sizeof(int32_t));
EricLew 9:5a860b9c8a6a 436 #else
EricLew 9:5a860b9c8a6a 437 hAudioIn.LeftRecBuff = (int32_t *)malloc(size * sizeof(int32_t));
EricLew 9:5a860b9c8a6a 438 #endif
EricLew 9:5a860b9c8a6a 439 if(hAudioIn.LeftRecBuff == NULL)
EricLew 9:5a860b9c8a6a 440 {
EricLew 9:5a860b9c8a6a 441 return AUDIO_ERROR;
EricLew 9:5a860b9c8a6a 442 }
EricLew 9:5a860b9c8a6a 443
EricLew 9:5a860b9c8a6a 444 /* Call the Media layer start function for left channel */
EricLew 9:5a860b9c8a6a 445 if(HAL_DFSDM_FilterRegularStart_DMA(&BSP_AUDIO_hDfsdmLeftFilter,
EricLew 9:5a860b9c8a6a 446 (int32_t*)hAudioIn.LeftRecBuff,
EricLew 9:5a860b9c8a6a 447 (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR)) != HAL_OK)
EricLew 9:5a860b9c8a6a 448 {
EricLew 9:5a860b9c8a6a 449 return AUDIO_ERROR;
EricLew 9:5a860b9c8a6a 450 }
EricLew 9:5a860b9c8a6a 451
EricLew 9:5a860b9c8a6a 452 return AUDIO_OK;
EricLew 9:5a860b9c8a6a 453 }
EricLew 9:5a860b9c8a6a 454
EricLew 9:5a860b9c8a6a 455 /**
EricLew 9:5a860b9c8a6a 456 * @brief Updates the audio frequency.
EricLew 9:5a860b9c8a6a 457 * @param AudioFreq: Audio frequency used to record the audio stream.
EricLew 9:5a860b9c8a6a 458 * @note This API should be called after the BSP_AUDIO_IN_Init() to adjust the
EricLew 9:5a860b9c8a6a 459 * audio frequency.
EricLew 9:5a860b9c8a6a 460 * @retval BSP AUDIO status
EricLew 9:5a860b9c8a6a 461 */
EricLew 9:5a860b9c8a6a 462 uint8_t BSP_AUDIO_IN_SetFrequency(uint32_t AudioFreq)
EricLew 9:5a860b9c8a6a 463 {
EricLew 9:5a860b9c8a6a 464 /* Configure the SAI PLL according to the requested audio frequency */
EricLew 9:5a860b9c8a6a 465 if (AUDIO_SAIPLLConfig(AudioFreq) != AUDIO_OK)
EricLew 9:5a860b9c8a6a 466 {
EricLew 9:5a860b9c8a6a 467 return AUDIO_ERROR;
EricLew 9:5a860b9c8a6a 468 }
EricLew 9:5a860b9c8a6a 469
EricLew 9:5a860b9c8a6a 470 /* De-initializes the Digital Filter for Sigma-Delta Modulators interface */
EricLew 9:5a860b9c8a6a 471 if(AUDIO_DFSDMx_DeInit() != AUDIO_OK)
EricLew 9:5a860b9c8a6a 472 {
EricLew 9:5a860b9c8a6a 473 return AUDIO_ERROR;
EricLew 9:5a860b9c8a6a 474 }
EricLew 9:5a860b9c8a6a 475
EricLew 9:5a860b9c8a6a 476 /* Initializes the Digital Filter for Sigma-Delta Modulators interface */
EricLew 9:5a860b9c8a6a 477 if(AUDIO_DFSDMx_Init(AudioFreq) != AUDIO_OK)
EricLew 9:5a860b9c8a6a 478 {
EricLew 9:5a860b9c8a6a 479 return AUDIO_ERROR;
EricLew 9:5a860b9c8a6a 480 }
EricLew 9:5a860b9c8a6a 481
EricLew 9:5a860b9c8a6a 482 return AUDIO_OK;
EricLew 9:5a860b9c8a6a 483 }
EricLew 9:5a860b9c8a6a 484
EricLew 9:5a860b9c8a6a 485 /**
EricLew 9:5a860b9c8a6a 486 * @brief Regular conversion complete callback.
EricLew 9:5a860b9c8a6a 487 * @note In interrupt mode, user has to read conversion value in this function
EricLew 9:5a860b9c8a6a 488 using HAL_DFSDM_FilterGetRegularValue.
EricLew 9:5a860b9c8a6a 489 * @param hdfsdm_filter : DFSDM filter handle.
EricLew 9:5a860b9c8a6a 490 * @retval None
EricLew 9:5a860b9c8a6a 491 */
EricLew 9:5a860b9c8a6a 492 void HAL_DFSDM_FilterRegConvCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
EricLew 9:5a860b9c8a6a 493 {
EricLew 9:5a860b9c8a6a 494 uint32_t index;
EricLew 9:5a860b9c8a6a 495 uint32_t recbufsize = (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR);
EricLew 9:5a860b9c8a6a 496
EricLew 9:5a860b9c8a6a 497 for(index = (recbufsize/2); index < recbufsize; index++)
EricLew 9:5a860b9c8a6a 498 {
EricLew 9:5a860b9c8a6a 499 hAudioIn.pRecBuf[index] = (uint16_t)(SaturaLH((hAudioIn.LeftRecBuff[index] >> 8), -32760, 32760));
EricLew 9:5a860b9c8a6a 500 }
EricLew 9:5a860b9c8a6a 501
EricLew 9:5a860b9c8a6a 502 /* Invoke the registered 'TransferComplete' function (if any) */
EricLew 9:5a860b9c8a6a 503 if (hAudioIn.CbTransferComplete != (Audio_CallbackTypeDef)NULL)
EricLew 9:5a860b9c8a6a 504 {
EricLew 9:5a860b9c8a6a 505 hAudioIn.CbTransferComplete();
EricLew 9:5a860b9c8a6a 506 }
EricLew 9:5a860b9c8a6a 507 }
EricLew 9:5a860b9c8a6a 508
EricLew 9:5a860b9c8a6a 509 /**
EricLew 9:5a860b9c8a6a 510 * @brief Half regular conversion complete callback.
EricLew 9:5a860b9c8a6a 511 * @param hdfsdm_filter : DFSDM filter handle.
EricLew 9:5a860b9c8a6a 512 * @retval None
EricLew 9:5a860b9c8a6a 513 */
EricLew 9:5a860b9c8a6a 514 void HAL_DFSDM_FilterRegConvHalfCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
EricLew 9:5a860b9c8a6a 515 {
EricLew 9:5a860b9c8a6a 516 uint32_t index;
EricLew 9:5a860b9c8a6a 517 uint32_t recbufsize = (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR);
EricLew 9:5a860b9c8a6a 518
EricLew 9:5a860b9c8a6a 519
EricLew 9:5a860b9c8a6a 520 for(index = 0; index < (recbufsize/2); index++)
EricLew 9:5a860b9c8a6a 521 {
EricLew 9:5a860b9c8a6a 522 hAudioIn.pRecBuf[index] = (uint16_t)(SaturaLH((hAudioIn.LeftRecBuff[index] >> 8), -32760, 32760));
EricLew 9:5a860b9c8a6a 523 }
EricLew 9:5a860b9c8a6a 524
EricLew 9:5a860b9c8a6a 525 /* Invoke the registered 'HalfTransfer' callback function (if any) */
EricLew 9:5a860b9c8a6a 526 if (hAudioIn.CbHalfTransfer != (Audio_CallbackTypeDef)NULL)
EricLew 9:5a860b9c8a6a 527 {
EricLew 9:5a860b9c8a6a 528 hAudioIn.CbHalfTransfer();
EricLew 9:5a860b9c8a6a 529 }
EricLew 9:5a860b9c8a6a 530 }
EricLew 9:5a860b9c8a6a 531
EricLew 9:5a860b9c8a6a 532 /**
EricLew 9:5a860b9c8a6a 533 * @brief Error callback.
EricLew 9:5a860b9c8a6a 534 * @param hdfsdm_filter : DFSDM filter handle.
EricLew 9:5a860b9c8a6a 535 * @retval None
EricLew 9:5a860b9c8a6a 536 */
EricLew 9:5a860b9c8a6a 537 void HAL_DFSDM_FilterErrorCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
EricLew 9:5a860b9c8a6a 538 {
EricLew 9:5a860b9c8a6a 539 /* Invoke the registered 'ErrorCallback' callback function (if any) */
EricLew 9:5a860b9c8a6a 540 if (hAudioIn.CbError != (Audio_CallbackTypeDef)NULL)
EricLew 9:5a860b9c8a6a 541 {
EricLew 9:5a860b9c8a6a 542 hAudioIn.CbError();
EricLew 9:5a860b9c8a6a 543 }
EricLew 9:5a860b9c8a6a 544 }
EricLew 9:5a860b9c8a6a 545
EricLew 9:5a860b9c8a6a 546 /**
EricLew 9:5a860b9c8a6a 547 * @brief Stops audio recording.
EricLew 9:5a860b9c8a6a 548 * @retval BSP AUDIO status
EricLew 9:5a860b9c8a6a 549 */
EricLew 9:5a860b9c8a6a 550 uint8_t BSP_AUDIO_IN_Stop(void)
EricLew 9:5a860b9c8a6a 551 {
EricLew 9:5a860b9c8a6a 552 /* Call the Media layer stop function for left channel */
EricLew 9:5a860b9c8a6a 553 if(HAL_DFSDM_FilterRegularStop_DMA(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK )
EricLew 9:5a860b9c8a6a 554 {
EricLew 9:5a860b9c8a6a 555 return AUDIO_ERROR;
EricLew 9:5a860b9c8a6a 556 }
EricLew 9:5a860b9c8a6a 557
EricLew 9:5a860b9c8a6a 558 /* Free hAudioIn.LeftRecBuff buffer */
EricLew 9:5a860b9c8a6a 559 #if defined(BSP_AUDIO_USE_RTOS)
EricLew 9:5a860b9c8a6a 560 k_free((void *)hAudioIn.LeftRecBuff);
EricLew 9:5a860b9c8a6a 561 #else
EricLew 9:5a860b9c8a6a 562 free((void *)hAudioIn.LeftRecBuff);
EricLew 9:5a860b9c8a6a 563 #endif
EricLew 9:5a860b9c8a6a 564
EricLew 9:5a860b9c8a6a 565 return AUDIO_OK;
EricLew 9:5a860b9c8a6a 566 }
EricLew 9:5a860b9c8a6a 567
EricLew 9:5a860b9c8a6a 568 /**
EricLew 9:5a860b9c8a6a 569 * @brief Pauses the audio file stream.
EricLew 9:5a860b9c8a6a 570 * @retval BSP AUDIO status
EricLew 9:5a860b9c8a6a 571 */
EricLew 9:5a860b9c8a6a 572 uint8_t BSP_AUDIO_IN_Pause(void)
EricLew 9:5a860b9c8a6a 573 {
EricLew 9:5a860b9c8a6a 574 /* Call the Media layer stop function */
EricLew 9:5a860b9c8a6a 575 if(HAL_DFSDM_FilterRegularStop_DMA(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK)
EricLew 9:5a860b9c8a6a 576 {
EricLew 9:5a860b9c8a6a 577 return AUDIO_ERROR;
EricLew 9:5a860b9c8a6a 578 }
EricLew 9:5a860b9c8a6a 579
EricLew 9:5a860b9c8a6a 580 return AUDIO_OK;
EricLew 9:5a860b9c8a6a 581 }
EricLew 9:5a860b9c8a6a 582
EricLew 9:5a860b9c8a6a 583 /**
EricLew 9:5a860b9c8a6a 584 * @brief Resumes the audio file stream.
EricLew 9:5a860b9c8a6a 585 * @retval BSP AUDIO status
EricLew 9:5a860b9c8a6a 586 */
EricLew 9:5a860b9c8a6a 587 uint8_t BSP_AUDIO_IN_Resume(void)
EricLew 9:5a860b9c8a6a 588 {
EricLew 9:5a860b9c8a6a 589 /* Call the Media layer start function for left channel */
EricLew 9:5a860b9c8a6a 590 if(HAL_DFSDM_FilterRegularStart_DMA(&BSP_AUDIO_hDfsdmLeftFilter,
EricLew 9:5a860b9c8a6a 591 (int32_t*)hAudioIn.LeftRecBuff,
EricLew 9:5a860b9c8a6a 592 (hAudioIn.RecSize/DEFAULT_AUDIO_IN_CHANNEL_NBR)) != HAL_OK)
EricLew 9:5a860b9c8a6a 593 {
EricLew 9:5a860b9c8a6a 594 return AUDIO_ERROR;
EricLew 9:5a860b9c8a6a 595 }
EricLew 9:5a860b9c8a6a 596
EricLew 9:5a860b9c8a6a 597 return AUDIO_OK;
EricLew 9:5a860b9c8a6a 598 }
EricLew 9:5a860b9c8a6a 599
EricLew 9:5a860b9c8a6a 600 /**
EricLew 9:5a860b9c8a6a 601 * @brief register user callback functions
EricLew 9:5a860b9c8a6a 602 * @param ErrorCallback: pointer to the error callback function
EricLew 9:5a860b9c8a6a 603 * @param HalfTransferCallback: pointer to the half transfer callback function
EricLew 9:5a860b9c8a6a 604 * @param TransferCompleteCallback: pointer to the transfer complete callback function
EricLew 9:5a860b9c8a6a 605 * @retval None
EricLew 9:5a860b9c8a6a 606 */
EricLew 9:5a860b9c8a6a 607 void BSP_AUDIO_IN_RegisterCallbacks(Audio_CallbackTypeDef ErrorCallback,
EricLew 9:5a860b9c8a6a 608 Audio_CallbackTypeDef HalfTransferCallback,
EricLew 9:5a860b9c8a6a 609 Audio_CallbackTypeDef TransferCompleteCallback)
EricLew 9:5a860b9c8a6a 610 {
EricLew 9:5a860b9c8a6a 611 hAudioIn.CbError = ErrorCallback;
EricLew 9:5a860b9c8a6a 612 hAudioIn.CbHalfTransfer = HalfTransferCallback;
EricLew 9:5a860b9c8a6a 613 hAudioIn.CbTransferComplete = TransferCompleteCallback;
EricLew 9:5a860b9c8a6a 614 }
EricLew 9:5a860b9c8a6a 615 /**
EricLew 9:5a860b9c8a6a 616 * @}
EricLew 9:5a860b9c8a6a 617 */
EricLew 9:5a860b9c8a6a 618
EricLew 9:5a860b9c8a6a 619 /* private functions --------------------------------------------------------*/
EricLew 9:5a860b9c8a6a 620 /** @addtogroup STM32L476G_DISCOVERY_AUDIO_Private_Functions
EricLew 9:5a860b9c8a6a 621 * @{
EricLew 9:5a860b9c8a6a 622 */
EricLew 9:5a860b9c8a6a 623 /**
EricLew 9:5a860b9c8a6a 624 * @brief Initializes the Audio Codec audio interface (SAI).
EricLew 9:5a860b9c8a6a 625 * @param AudioFreq: Audio frequency to be configured for the SAI peripheral.
EricLew 9:5a860b9c8a6a 626 * @note The default SlotActive configuration is set to CODEC_AUDIOFRAME_SLOT_0123
EricLew 9:5a860b9c8a6a 627 * and user can update this configuration using
EricLew 9:5a860b9c8a6a 628 * @retval BSP AUDIO status
EricLew 9:5a860b9c8a6a 629 */
EricLew 9:5a860b9c8a6a 630 static uint8_t AUDIO_SAIx_Init(uint32_t AudioFreq)
EricLew 9:5a860b9c8a6a 631 {
EricLew 9:5a860b9c8a6a 632 /* Disable SAI peripheral to allow access to SAI internal registers */
EricLew 9:5a860b9c8a6a 633 __HAL_SAI_DISABLE(&BSP_AUDIO_hSai);
EricLew 9:5a860b9c8a6a 634
EricLew 9:5a860b9c8a6a 635 /* Initialize the BSP_AUDIO_hSai Instance parameter */
EricLew 9:5a860b9c8a6a 636 BSP_AUDIO_hSai.Instance = AUDIO_SAIx;
EricLew 9:5a860b9c8a6a 637
EricLew 9:5a860b9c8a6a 638 /* Configure SAI_Block_x
EricLew 9:5a860b9c8a6a 639 LSBFirst: Disabled
EricLew 9:5a860b9c8a6a 640 DataSize: 16 */
EricLew 9:5a860b9c8a6a 641 BSP_AUDIO_hSai.Init.AudioMode = SAI_MODEMASTER_TX;
EricLew 9:5a860b9c8a6a 642 BSP_AUDIO_hSai.Init.Synchro = SAI_ASYNCHRONOUS;
EricLew 9:5a860b9c8a6a 643 BSP_AUDIO_hSai.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
EricLew 9:5a860b9c8a6a 644 BSP_AUDIO_hSai.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
EricLew 9:5a860b9c8a6a 645 BSP_AUDIO_hSai.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
EricLew 9:5a860b9c8a6a 646 BSP_AUDIO_hSai.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
EricLew 9:5a860b9c8a6a 647 BSP_AUDIO_hSai.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_MCKDIV;
EricLew 9:5a860b9c8a6a 648 BSP_AUDIO_hSai.Init.Mckdiv = SAIClockDivider(AudioFreq);
EricLew 9:5a860b9c8a6a 649 BSP_AUDIO_hSai.Init.MonoStereoMode = SAI_STEREOMODE;
EricLew 9:5a860b9c8a6a 650 BSP_AUDIO_hSai.Init.CompandingMode = SAI_NOCOMPANDING;
EricLew 9:5a860b9c8a6a 651 BSP_AUDIO_hSai.Init.TriState = SAI_OUTPUT_NOTRELEASED;
EricLew 9:5a860b9c8a6a 652 BSP_AUDIO_hSai.Init.Protocol = SAI_FREE_PROTOCOL;
EricLew 9:5a860b9c8a6a 653 BSP_AUDIO_hSai.Init.DataSize = SAI_DATASIZE_16;
EricLew 9:5a860b9c8a6a 654 BSP_AUDIO_hSai.Init.FirstBit = SAI_FIRSTBIT_MSB;
EricLew 9:5a860b9c8a6a 655 BSP_AUDIO_hSai.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
EricLew 9:5a860b9c8a6a 656
EricLew 9:5a860b9c8a6a 657 /* Configure SAI_Block_x Frame
EricLew 9:5a860b9c8a6a 658 Frame Length: 32
EricLew 9:5a860b9c8a6a 659 Frame active Length: 16
EricLew 9:5a860b9c8a6a 660 FS Definition: Start frame + Channel Side identification
EricLew 9:5a860b9c8a6a 661 FS Polarity: FS active Low
EricLew 9:5a860b9c8a6a 662 FS Offset: FS asserted one bit before the first bit of slot 0 */
EricLew 9:5a860b9c8a6a 663 BSP_AUDIO_hSai.FrameInit.FrameLength = 32;
EricLew 9:5a860b9c8a6a 664 BSP_AUDIO_hSai.FrameInit.ActiveFrameLength = 16;
EricLew 9:5a860b9c8a6a 665 BSP_AUDIO_hSai.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
EricLew 9:5a860b9c8a6a 666 BSP_AUDIO_hSai.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
EricLew 9:5a860b9c8a6a 667 BSP_AUDIO_hSai.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
EricLew 9:5a860b9c8a6a 668
EricLew 9:5a860b9c8a6a 669 /* Configure SAI Block_x Slot
EricLew 9:5a860b9c8a6a 670 Slot First Bit Offset: 0
EricLew 9:5a860b9c8a6a 671 Slot Size : 16
EricLew 9:5a860b9c8a6a 672 Slot Number: 2
EricLew 9:5a860b9c8a6a 673 Slot Active: Slots 0 and 1 actives */
EricLew 9:5a860b9c8a6a 674 BSP_AUDIO_hSai.SlotInit.FirstBitOffset = 0;
EricLew 9:5a860b9c8a6a 675 BSP_AUDIO_hSai.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
EricLew 9:5a860b9c8a6a 676 BSP_AUDIO_hSai.SlotInit.SlotNumber = 2;
EricLew 9:5a860b9c8a6a 677 BSP_AUDIO_hSai.SlotInit.SlotActive = SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1;
EricLew 9:5a860b9c8a6a 678
EricLew 9:5a860b9c8a6a 679 /* Initializes the SAI peripheral*/
EricLew 9:5a860b9c8a6a 680 if (HAL_SAI_Init(&BSP_AUDIO_hSai) != HAL_OK)
EricLew 9:5a860b9c8a6a 681 {
EricLew 9:5a860b9c8a6a 682 return AUDIO_ERROR;
EricLew 9:5a860b9c8a6a 683 }
EricLew 9:5a860b9c8a6a 684
EricLew 9:5a860b9c8a6a 685 /* Enable SAI peripheral to generate MCLK */
EricLew 9:5a860b9c8a6a 686 __HAL_SAI_ENABLE(&BSP_AUDIO_hSai);
EricLew 9:5a860b9c8a6a 687
EricLew 9:5a860b9c8a6a 688 return AUDIO_OK;
EricLew 9:5a860b9c8a6a 689
EricLew 9:5a860b9c8a6a 690 }
EricLew 9:5a860b9c8a6a 691
EricLew 9:5a860b9c8a6a 692 /**
EricLew 9:5a860b9c8a6a 693 * @brief De-initializes the Audio Codec audio interface (SAI).
EricLew 9:5a860b9c8a6a 694 * @retval BSP AUDIO status
EricLew 9:5a860b9c8a6a 695 */
EricLew 9:5a860b9c8a6a 696 static uint8_t AUDIO_SAIx_DeInit(void)
EricLew 9:5a860b9c8a6a 697 {
EricLew 9:5a860b9c8a6a 698 /* Disable the SAI audio block */
EricLew 9:5a860b9c8a6a 699 __HAL_SAI_DISABLE(&BSP_AUDIO_hSai);
EricLew 9:5a860b9c8a6a 700
EricLew 9:5a860b9c8a6a 701 /* De-initializes the SAI peripheral */
EricLew 9:5a860b9c8a6a 702 if (HAL_SAI_DeInit(&BSP_AUDIO_hSai) != HAL_OK)
EricLew 9:5a860b9c8a6a 703 {
EricLew 9:5a860b9c8a6a 704 return AUDIO_ERROR;
EricLew 9:5a860b9c8a6a 705 }
EricLew 9:5a860b9c8a6a 706
EricLew 9:5a860b9c8a6a 707 /* Disable SAIx PLL */
EricLew 9:5a860b9c8a6a 708 if (AUDIO_SAIx_PLL_DISABLE() != AUDIO_OK)
EricLew 9:5a860b9c8a6a 709 {
EricLew 9:5a860b9c8a6a 710 return AUDIO_ERROR;
EricLew 9:5a860b9c8a6a 711 }
EricLew 9:5a860b9c8a6a 712
EricLew 9:5a860b9c8a6a 713 return AUDIO_OK;
EricLew 9:5a860b9c8a6a 714 }
EricLew 9:5a860b9c8a6a 715
EricLew 9:5a860b9c8a6a 716 /**
EricLew 9:5a860b9c8a6a 717 * @brief SAI MSP Init
EricLew 9:5a860b9c8a6a 718 * @param hsai : pointer to a SAI_HandleTypeDef structure
EricLew 9:5a860b9c8a6a 719 * @retval None
EricLew 9:5a860b9c8a6a 720 */
EricLew 9:5a860b9c8a6a 721 void HAL_SAI_MspInit(SAI_HandleTypeDef *hsai)
EricLew 9:5a860b9c8a6a 722 {
EricLew 9:5a860b9c8a6a 723 GPIO_InitTypeDef GPIO_InitStruct;
EricLew 9:5a860b9c8a6a 724
EricLew 9:5a860b9c8a6a 725 /* Enable SAI clock */
EricLew 9:5a860b9c8a6a 726 AUDIO_SAIx_CLK_ENABLE();
EricLew 9:5a860b9c8a6a 727
EricLew 9:5a860b9c8a6a 728 /* Enable GPIO clock */
EricLew 9:5a860b9c8a6a 729 AUDIO_SAIx_MCK_SCK_SD_FS_ENABLE();
EricLew 9:5a860b9c8a6a 730
EricLew 9:5a860b9c8a6a 731 /* CODEC_SAI pins configuration: FS, SCK, MCK and SD pins ------------------*/
EricLew 9:5a860b9c8a6a 732 GPIO_InitStruct.Pin = AUDIO_SAIx_FS_PIN | AUDIO_SAIx_SCK_PIN | AUDIO_SAIx_SD_PIN | AUDIO_SAIx_MCK_PIN;
EricLew 9:5a860b9c8a6a 733 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
EricLew 9:5a860b9c8a6a 734 GPIO_InitStruct.Pull = GPIO_NOPULL;
EricLew 9:5a860b9c8a6a 735 GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
EricLew 9:5a860b9c8a6a 736 GPIO_InitStruct.Alternate = AUDIO_SAIx_MCK_SCK_SD_FS_AF;
EricLew 9:5a860b9c8a6a 737 HAL_GPIO_Init(AUDIO_SAIx_MCK_SCK_SD_FS_GPIO_PORT, &GPIO_InitStruct);
EricLew 9:5a860b9c8a6a 738
EricLew 9:5a860b9c8a6a 739 /* Enable the DMA clock */
EricLew 9:5a860b9c8a6a 740 AUDIO_SAIx_DMAx_CLK_ENABLE();
EricLew 9:5a860b9c8a6a 741
EricLew 9:5a860b9c8a6a 742 if(hsai->Instance == AUDIO_SAIx)
EricLew 9:5a860b9c8a6a 743 {
EricLew 9:5a860b9c8a6a 744 /* Configure the hDmaSai handle parameters */
EricLew 9:5a860b9c8a6a 745 hDmaSai.Init.Request = DMA_REQUEST_1;
EricLew 9:5a860b9c8a6a 746 hDmaSai.Init.Direction = DMA_MEMORY_TO_PERIPH;
EricLew 9:5a860b9c8a6a 747 hDmaSai.Init.PeriphInc = DMA_PINC_DISABLE;
EricLew 9:5a860b9c8a6a 748 hDmaSai.Init.MemInc = DMA_MINC_ENABLE;
EricLew 9:5a860b9c8a6a 749 hDmaSai.Init.PeriphDataAlignment = AUDIO_SAIx_DMAx_PERIPH_DATA_SIZE;
EricLew 9:5a860b9c8a6a 750 hDmaSai.Init.MemDataAlignment = AUDIO_SAIx_DMAx_MEM_DATA_SIZE;
EricLew 9:5a860b9c8a6a 751 hDmaSai.Init.Mode = DMA_NORMAL;
EricLew 9:5a860b9c8a6a 752 hDmaSai.Init.Priority = DMA_PRIORITY_HIGH;
EricLew 9:5a860b9c8a6a 753
EricLew 9:5a860b9c8a6a 754 hDmaSai.Instance = AUDIO_SAIx_DMAx_CHANNEL;
EricLew 9:5a860b9c8a6a 755
EricLew 9:5a860b9c8a6a 756 /* Associate the DMA handle */
EricLew 9:5a860b9c8a6a 757 __HAL_LINKDMA(hsai, hdmatx, hDmaSai);
EricLew 9:5a860b9c8a6a 758
EricLew 9:5a860b9c8a6a 759 /* Deinitialize the Stream for new transfer */
EricLew 9:5a860b9c8a6a 760 HAL_DMA_DeInit(&hDmaSai);
EricLew 9:5a860b9c8a6a 761
EricLew 9:5a860b9c8a6a 762 /* Configure the DMA Stream */
EricLew 9:5a860b9c8a6a 763 HAL_DMA_Init(&hDmaSai);
EricLew 9:5a860b9c8a6a 764 }
EricLew 9:5a860b9c8a6a 765
EricLew 9:5a860b9c8a6a 766 /* SAI DMA IRQ Channel configuration */
EricLew 9:5a860b9c8a6a 767 HAL_NVIC_SetPriority(AUDIO_SAIx_DMAx_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0);
EricLew 9:5a860b9c8a6a 768 HAL_NVIC_EnableIRQ(AUDIO_SAIx_DMAx_IRQ);
EricLew 9:5a860b9c8a6a 769 }
EricLew 9:5a860b9c8a6a 770
EricLew 9:5a860b9c8a6a 771 /**
EricLew 9:5a860b9c8a6a 772 * @brief SAI MSP De-init
EricLew 9:5a860b9c8a6a 773 * @param hsai : pointer to a SAI_HandleTypeDef structure
EricLew 9:5a860b9c8a6a 774 * @retval None
EricLew 9:5a860b9c8a6a 775 */
EricLew 9:5a860b9c8a6a 776 void HAL_SAI_MspDeInit(SAI_HandleTypeDef *hsai)
EricLew 9:5a860b9c8a6a 777 {
EricLew 9:5a860b9c8a6a 778 /* Disable SAI DMA Channel IRQ */
EricLew 9:5a860b9c8a6a 779 HAL_NVIC_DisableIRQ(AUDIO_SAIx_DMAx_IRQ);
EricLew 9:5a860b9c8a6a 780
EricLew 9:5a860b9c8a6a 781 /* Reset the DMA Stream configuration*/
EricLew 9:5a860b9c8a6a 782 HAL_DMA_DeInit(&hDmaSai);
EricLew 9:5a860b9c8a6a 783
EricLew 9:5a860b9c8a6a 784 /* Disable the DMA clock */
EricLew 9:5a860b9c8a6a 785 AUDIO_SAIx_DMAx_CLK_DISABLE();
EricLew 9:5a860b9c8a6a 786
EricLew 9:5a860b9c8a6a 787 /* De-initialize FS, SCK, MCK and SD pins*/
EricLew 9:5a860b9c8a6a 788 HAL_GPIO_DeInit(AUDIO_SAIx_MCK_SCK_SD_FS_GPIO_PORT,
EricLew 9:5a860b9c8a6a 789 AUDIO_SAIx_FS_PIN | AUDIO_SAIx_SCK_PIN | AUDIO_SAIx_SD_PIN | AUDIO_SAIx_MCK_PIN);
EricLew 9:5a860b9c8a6a 790
EricLew 9:5a860b9c8a6a 791 /* Disable GPIO clock */
EricLew 9:5a860b9c8a6a 792 AUDIO_SAIx_MCK_SCK_SD_FS_DISABLE();
EricLew 9:5a860b9c8a6a 793
EricLew 9:5a860b9c8a6a 794 /* Disable SAI clock */
EricLew 9:5a860b9c8a6a 795 AUDIO_SAIx_CLK_DISABLE();
EricLew 9:5a860b9c8a6a 796 }
EricLew 9:5a860b9c8a6a 797
EricLew 9:5a860b9c8a6a 798 /**
EricLew 9:5a860b9c8a6a 799 * @brief Resets the audio codec. It restores the default configuration of the
EricLew 9:5a860b9c8a6a 800 * codec (this function shall be called before initializing the codec).
EricLew 9:5a860b9c8a6a 801 * @retval None
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
EricLew 9:5a860b9c8a6a 809 /** @addtogroup STM32L476G_DISCOVERY_AUDIO_Private_Functions
EricLew 9:5a860b9c8a6a 810 * @{
EricLew 9:5a860b9c8a6a 811 */
EricLew 9:5a860b9c8a6a 812
EricLew 9:5a860b9c8a6a 813 /**
EricLew 9:5a860b9c8a6a 814 * @brief Initializes the Digital Filter for Sigma-Delta Modulators interface (DFSDM).
EricLew 9:5a860b9c8a6a 815 * @param AudioFreq: Audio frequency to be used to set correctly the DFSDM peripheral.
EricLew 9:5a860b9c8a6a 816 * @retval BSP AUDIO status
EricLew 9:5a860b9c8a6a 817 */
EricLew 9:5a860b9c8a6a 818 static uint8_t AUDIO_DFSDMx_Init(uint32_t AudioFreq)
EricLew 9:5a860b9c8a6a 819 {
EricLew 9:5a860b9c8a6a 820 /*####CHANNEL 2####*/
EricLew 9:5a860b9c8a6a 821 hAudioIn.hDfsdmLeftChannel.Init.OutputClock.Activation = ENABLE;
EricLew 9:5a860b9c8a6a 822 hAudioIn.hDfsdmLeftChannel.Init.OutputClock.Selection = DFSDM_CHANNEL_OUTPUT_CLOCK_AUDIO;
EricLew 9:5a860b9c8a6a 823 /* Set the DFSDM clock OUT audio frequency configuration */
EricLew 9:5a860b9c8a6a 824 hAudioIn.hDfsdmLeftChannel.Init.OutputClock.Divider = DFSDMClockDivider(AudioFreq);
EricLew 9:5a860b9c8a6a 825 hAudioIn.hDfsdmLeftChannel.Init.Input.Multiplexer = DFSDM_CHANNEL_EXTERNAL_INPUTS;
EricLew 9:5a860b9c8a6a 826 hAudioIn.hDfsdmLeftChannel.Init.Input.DataPacking = DFSDM_CHANNEL_STANDARD_MODE;
EricLew 9:5a860b9c8a6a 827 hAudioIn.hDfsdmLeftChannel.Init.Input.Pins = DFSDM_CHANNEL_SAME_CHANNEL_PINS;
EricLew 9:5a860b9c8a6a 828 /* Request to sample stable data for LEFT micro on Rising edge */
EricLew 9:5a860b9c8a6a 829 hAudioIn.hDfsdmLeftChannel.Init.SerialInterface.Type = DFSDM_CHANNEL_SPI_RISING;
EricLew 9:5a860b9c8a6a 830 hAudioIn.hDfsdmLeftChannel.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
EricLew 9:5a860b9c8a6a 831 hAudioIn.hDfsdmLeftChannel.Init.Awd.FilterOrder = DFSDM_CHANNEL_SINC1_ORDER;
EricLew 9:5a860b9c8a6a 832 hAudioIn.hDfsdmLeftChannel.Init.Awd.Oversampling = 10;
EricLew 9:5a860b9c8a6a 833 hAudioIn.hDfsdmLeftChannel.Init.Offset = 0;
EricLew 9:5a860b9c8a6a 834 hAudioIn.hDfsdmLeftChannel.Init.RightBitShift = DFSDMRightBitShift(AudioFreq);
EricLew 9:5a860b9c8a6a 835
linx0576 10:0986108f8aa3 836 hAudioIn.hDfsdmLeftChannel.Instance = DFSDM_Channel4;
EricLew 9:5a860b9c8a6a 837
EricLew 9:5a860b9c8a6a 838 /* Init the DFSDM Channel */
EricLew 9:5a860b9c8a6a 839 if (HAL_DFSDM_ChannelInit(&hAudioIn.hDfsdmLeftChannel) != HAL_OK)
EricLew 9:5a860b9c8a6a 840 {
EricLew 9:5a860b9c8a6a 841 return AUDIO_ERROR;
EricLew 9:5a860b9c8a6a 842 }
EricLew 9:5a860b9c8a6a 843
EricLew 9:5a860b9c8a6a 844 /*####FILTER 0####*/
EricLew 9:5a860b9c8a6a 845 BSP_AUDIO_hDfsdmLeftFilter.Init.RegularParam.Trigger = DFSDM_FILTER_SW_TRIGGER;
EricLew 9:5a860b9c8a6a 846 BSP_AUDIO_hDfsdmLeftFilter.Init.RegularParam.FastMode = ENABLE;
EricLew 9:5a860b9c8a6a 847 BSP_AUDIO_hDfsdmLeftFilter.Init.RegularParam.DmaMode = ENABLE;
EricLew 9:5a860b9c8a6a 848 BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.Trigger = DFSDM_FILTER_SW_TRIGGER;
EricLew 9:5a860b9c8a6a 849 BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.ScanMode = DISABLE;
EricLew 9:5a860b9c8a6a 850 BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.DmaMode = DISABLE;
EricLew 9:5a860b9c8a6a 851 BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.ExtTrigger = DFSDM_FILTER_EXT_TRIG_TIM8_TRGO;
EricLew 9:5a860b9c8a6a 852 BSP_AUDIO_hDfsdmLeftFilter.Init.InjectedParam.ExtTriggerEdge = DFSDM_FILTER_EXT_TRIG_BOTH_EDGES;
EricLew 9:5a860b9c8a6a 853 BSP_AUDIO_hDfsdmLeftFilter.Init.FilterParam.SincOrder = DFSDMFilterOrder(AudioFreq);
EricLew 9:5a860b9c8a6a 854 /* Set the DFSDM Filters Oversampling to have correct sample rate */
EricLew 9:5a860b9c8a6a 855 BSP_AUDIO_hDfsdmLeftFilter.Init.FilterParam.Oversampling = DFSDMOverSampling(AudioFreq);
EricLew 9:5a860b9c8a6a 856 BSP_AUDIO_hDfsdmLeftFilter.Init.FilterParam.IntOversampling = 1;
EricLew 9:5a860b9c8a6a 857
EricLew 9:5a860b9c8a6a 858 BSP_AUDIO_hDfsdmLeftFilter.Instance = AUDIO_DFSDMx_LEFT_FILTER;
EricLew 9:5a860b9c8a6a 859
EricLew 9:5a860b9c8a6a 860 /* Init the DFSDM Filter */
EricLew 9:5a860b9c8a6a 861 if (HAL_DFSDM_FilterInit(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK)
EricLew 9:5a860b9c8a6a 862 {
EricLew 9:5a860b9c8a6a 863 return AUDIO_ERROR;
EricLew 9:5a860b9c8a6a 864 }
EricLew 9:5a860b9c8a6a 865
EricLew 9:5a860b9c8a6a 866 /* Configure regular channel */
EricLew 9:5a860b9c8a6a 867 if (HAL_DFSDM_FilterConfigRegChannel(&BSP_AUDIO_hDfsdmLeftFilter,
linx0576 10:0986108f8aa3 868 DFSDM_CHANNEL_4,
EricLew 9:5a860b9c8a6a 869 DFSDM_CONTINUOUS_CONV_ON) != HAL_OK)
EricLew 9:5a860b9c8a6a 870 {
EricLew 9:5a860b9c8a6a 871 return AUDIO_ERROR;
EricLew 9:5a860b9c8a6a 872 }
EricLew 9:5a860b9c8a6a 873
EricLew 9:5a860b9c8a6a 874 return AUDIO_OK;
EricLew 9:5a860b9c8a6a 875 }
EricLew 9:5a860b9c8a6a 876
EricLew 9:5a860b9c8a6a 877 /**
EricLew 9:5a860b9c8a6a 878 * @brief De-initializes the Digital Filter for Sigma-Delta Modulators interface (DFSDM).
EricLew 9:5a860b9c8a6a 879 * @retval BSP AUDIO status
EricLew 9:5a860b9c8a6a 880 */
EricLew 9:5a860b9c8a6a 881 static uint8_t AUDIO_DFSDMx_DeInit(void)
EricLew 9:5a860b9c8a6a 882 {
EricLew 9:5a860b9c8a6a 883 /* De-initializes the DFSDM filters to allow access to DFSDM internal registers */
EricLew 9:5a860b9c8a6a 884 if (HAL_DFSDM_FilterDeInit(&BSP_AUDIO_hDfsdmLeftFilter) != HAL_OK)
EricLew 9:5a860b9c8a6a 885 {
EricLew 9:5a860b9c8a6a 886 return AUDIO_ERROR;
EricLew 9:5a860b9c8a6a 887 }
EricLew 9:5a860b9c8a6a 888
EricLew 9:5a860b9c8a6a 889 /* De-initializes the DFSDM channels to allow access to DFSDM internal registers */
EricLew 9:5a860b9c8a6a 890 if (HAL_DFSDM_ChannelDeInit(&hAudioIn.hDfsdmLeftChannel) != HAL_OK)
EricLew 9:5a860b9c8a6a 891 {
EricLew 9:5a860b9c8a6a 892 return AUDIO_ERROR;
EricLew 9:5a860b9c8a6a 893 }
EricLew 9:5a860b9c8a6a 894
EricLew 9:5a860b9c8a6a 895 /* Disable DFSDM clock */
EricLew 9:5a860b9c8a6a 896 AUDIO_DFSDMx_CLK_DISABLE();
EricLew 9:5a860b9c8a6a 897
EricLew 9:5a860b9c8a6a 898 /* Disable SAIx PLL */
EricLew 9:5a860b9c8a6a 899 if (AUDIO_SAIx_PLL_DISABLE() != AUDIO_OK)
EricLew 9:5a860b9c8a6a 900 {
EricLew 9:5a860b9c8a6a 901 return AUDIO_ERROR;
EricLew 9:5a860b9c8a6a 902 }
EricLew 9:5a860b9c8a6a 903
EricLew 9:5a860b9c8a6a 904 /* DFSDM reset */
EricLew 9:5a860b9c8a6a 905 __HAL_RCC_DFSDM_FORCE_RESET();
EricLew 9:5a860b9c8a6a 906 __HAL_RCC_DFSDM_RELEASE_RESET();
EricLew 9:5a860b9c8a6a 907
EricLew 9:5a860b9c8a6a 908 return AUDIO_OK;
EricLew 9:5a860b9c8a6a 909 }
EricLew 9:5a860b9c8a6a 910
EricLew 9:5a860b9c8a6a 911 /**
EricLew 9:5a860b9c8a6a 912 * @brief Initializes the DFSDM channel MSP.
EricLew 9:5a860b9c8a6a 913 * @param hdfsdm_channel : DFSDM channel handle.
EricLew 9:5a860b9c8a6a 914 * @retval None
EricLew 9:5a860b9c8a6a 915 */
EricLew 9:5a860b9c8a6a 916 void HAL_DFSDM_ChannelMspInit(DFSDM_Channel_HandleTypeDef *hdfsdm_channel)
EricLew 9:5a860b9c8a6a 917 {
EricLew 9:5a860b9c8a6a 918 GPIO_InitTypeDef GPIO_InitStruct;
EricLew 9:5a860b9c8a6a 919
EricLew 9:5a860b9c8a6a 920 /* Enable DFSDM clock */
EricLew 9:5a860b9c8a6a 921 AUDIO_DFSDMx_CLK_ENABLE();
EricLew 9:5a860b9c8a6a 922
EricLew 9:5a860b9c8a6a 923 /* Enable GPIO clock */
EricLew 9:5a860b9c8a6a 924 AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_CLK_ENABLE();
EricLew 9:5a860b9c8a6a 925
EricLew 9:5a860b9c8a6a 926 /* DFSDM pins configuration: DFSDM_CKOUT, DMIC_DATIN pins ------------------*/
EricLew 9:5a860b9c8a6a 927 GPIO_InitStruct.Pin = AUDIO_DFSDMx_CKOUT_PIN | AUDIO_DFSDMx_DMIC_DATIN_PIN;
EricLew 9:5a860b9c8a6a 928 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
EricLew 9:5a860b9c8a6a 929 GPIO_InitStruct.Pull = GPIO_NOPULL;
EricLew 9:5a860b9c8a6a 930 GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
EricLew 9:5a860b9c8a6a 931 GPIO_InitStruct.Alternate = AUDIO_DFSDMx_CKOUT_DMIC_DATIN_AF;
EricLew 9:5a860b9c8a6a 932 HAL_GPIO_Init(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, &GPIO_InitStruct);
EricLew 9:5a860b9c8a6a 933 }
EricLew 9:5a860b9c8a6a 934
EricLew 9:5a860b9c8a6a 935 /**
EricLew 9:5a860b9c8a6a 936 * @brief De-initializes the DFSDM channel MSP.
EricLew 9:5a860b9c8a6a 937 * @param hdfsdm_channel : DFSDM channel handle.
EricLew 9:5a860b9c8a6a 938 * @retval None
EricLew 9:5a860b9c8a6a 939 */
EricLew 9:5a860b9c8a6a 940 void HAL_DFSDM_ChannelMspDeInit(DFSDM_Channel_HandleTypeDef *hdfsdm_channel)
EricLew 9:5a860b9c8a6a 941 {
EricLew 9:5a860b9c8a6a 942 GPIO_InitTypeDef GPIO_InitStruct;
EricLew 9:5a860b9c8a6a 943
EricLew 9:5a860b9c8a6a 944 /* Enable GPIO clock */
EricLew 9:5a860b9c8a6a 945 AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_CLK_ENABLE();
EricLew 9:5a860b9c8a6a 946
EricLew 9:5a860b9c8a6a 947 /* DFSDM pins configuration: DFSDM_CKOUT */
EricLew 9:5a860b9c8a6a 948 GPIO_InitStruct.Pin = AUDIO_DFSDMx_CKOUT_PIN;
EricLew 9:5a860b9c8a6a 949 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
EricLew 9:5a860b9c8a6a 950 GPIO_InitStruct.Pull = GPIO_NOPULL;
EricLew 9:5a860b9c8a6a 951 GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
EricLew 9:5a860b9c8a6a 952 HAL_GPIO_Init(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, &GPIO_InitStruct);
EricLew 9:5a860b9c8a6a 953 HAL_GPIO_WritePin(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, AUDIO_DFSDMx_CKOUT_PIN, GPIO_PIN_RESET);
EricLew 9:5a860b9c8a6a 954
EricLew 9:5a860b9c8a6a 955
EricLew 9:5a860b9c8a6a 956 /* De-initialize DMIC_DATIN pin */
EricLew 9:5a860b9c8a6a 957 HAL_GPIO_DeInit(AUDIO_DFSDMx_CKOUT_DMIC_DATIN_GPIO_PORT, AUDIO_DFSDMx_DMIC_DATIN_PIN);
EricLew 9:5a860b9c8a6a 958 }
EricLew 9:5a860b9c8a6a 959
EricLew 9:5a860b9c8a6a 960 /**
EricLew 9:5a860b9c8a6a 961 * @brief Initializes the DFSDM filter MSP.
EricLew 9:5a860b9c8a6a 962 * @param hdfsdm_filter : DFSDM filter handle.
EricLew 9:5a860b9c8a6a 963 * @retval None
EricLew 9:5a860b9c8a6a 964 */
EricLew 9:5a860b9c8a6a 965 void HAL_DFSDM_FilterMspInit(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
EricLew 9:5a860b9c8a6a 966 {
EricLew 9:5a860b9c8a6a 967 /* Enable DFSDM clock */
EricLew 9:5a860b9c8a6a 968 AUDIO_DFSDMx_CLK_ENABLE();
EricLew 9:5a860b9c8a6a 969
EricLew 9:5a860b9c8a6a 970 /* Enable the DMA clock */
EricLew 9:5a860b9c8a6a 971 AUDIO_DFSDMx_DMAx_CLK_ENABLE();
EricLew 9:5a860b9c8a6a 972
EricLew 9:5a860b9c8a6a 973 /* Configure the hAudioIn.hDmaDfsdmLeft handle parameters */
EricLew 9:5a860b9c8a6a 974 hAudioIn.hDmaDfsdmLeft.Init.Request = DMA_REQUEST_0;
EricLew 9:5a860b9c8a6a 975 hAudioIn.hDmaDfsdmLeft.Init.Direction = DMA_PERIPH_TO_MEMORY;
EricLew 9:5a860b9c8a6a 976 hAudioIn.hDmaDfsdmLeft.Init.PeriphInc = DMA_PINC_DISABLE;
EricLew 9:5a860b9c8a6a 977 hAudioIn.hDmaDfsdmLeft.Init.MemInc = DMA_MINC_ENABLE;
EricLew 9:5a860b9c8a6a 978 hAudioIn.hDmaDfsdmLeft.Init.PeriphDataAlignment = AUDIO_DFSDMx_DMAx_PERIPH_DATA_SIZE;
EricLew 9:5a860b9c8a6a 979 hAudioIn.hDmaDfsdmLeft.Init.MemDataAlignment = AUDIO_DFSDMx_DMAx_MEM_DATA_SIZE;
EricLew 9:5a860b9c8a6a 980 hAudioIn.hDmaDfsdmLeft.Init.Mode = DMA_CIRCULAR;
EricLew 9:5a860b9c8a6a 981 hAudioIn.hDmaDfsdmLeft.Init.Priority = DMA_PRIORITY_HIGH;
EricLew 9:5a860b9c8a6a 982
EricLew 9:5a860b9c8a6a 983 hAudioIn.hDmaDfsdmLeft.Instance = AUDIO_DFSDMx_DMAx_LEFT_CHANNEL;
EricLew 9:5a860b9c8a6a 984
EricLew 9:5a860b9c8a6a 985 /* Associate the DMA handle */
EricLew 9:5a860b9c8a6a 986 __HAL_LINKDMA(hdfsdm_filter, hdmaReg, hAudioIn.hDmaDfsdmLeft);
EricLew 9:5a860b9c8a6a 987
EricLew 9:5a860b9c8a6a 988 /* Reset DMA handle state */
EricLew 9:5a860b9c8a6a 989 __HAL_DMA_RESET_HANDLE_STATE(&hAudioIn.hDmaDfsdmLeft);
EricLew 9:5a860b9c8a6a 990
EricLew 9:5a860b9c8a6a 991 /* Configure the DMA Channel */
EricLew 9:5a860b9c8a6a 992 HAL_DMA_Init(&hAudioIn.hDmaDfsdmLeft);
EricLew 9:5a860b9c8a6a 993
EricLew 9:5a860b9c8a6a 994 /* DMA IRQ Channel configuration */
EricLew 9:5a860b9c8a6a 995 HAL_NVIC_SetPriority(AUDIO_DFSDMx_DMAx_LEFT_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0);
EricLew 9:5a860b9c8a6a 996 HAL_NVIC_EnableIRQ(AUDIO_DFSDMx_DMAx_LEFT_IRQ);
EricLew 9:5a860b9c8a6a 997 }
EricLew 9:5a860b9c8a6a 998
EricLew 9:5a860b9c8a6a 999 /**
EricLew 9:5a860b9c8a6a 1000 * @brief De-initializes the DFSDM filter MSP.
EricLew 9:5a860b9c8a6a 1001 * @param hdfsdm_filter : DFSDM filter handle.
EricLew 9:5a860b9c8a6a 1002 * @retval None
EricLew 9:5a860b9c8a6a 1003 */
EricLew 9:5a860b9c8a6a 1004 void HAL_DFSDM_FilterMspDeInit(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
EricLew 9:5a860b9c8a6a 1005 {
EricLew 9:5a860b9c8a6a 1006 /* Disable DMA Channel IRQ */
EricLew 9:5a860b9c8a6a 1007 HAL_NVIC_DisableIRQ(AUDIO_DFSDMx_DMAx_LEFT_IRQ);
EricLew 9:5a860b9c8a6a 1008
EricLew 9:5a860b9c8a6a 1009 /* De-initialize the DMA Channel */
EricLew 9:5a860b9c8a6a 1010 HAL_DMA_DeInit(&hAudioIn.hDmaDfsdmLeft);
EricLew 9:5a860b9c8a6a 1011
EricLew 9:5a860b9c8a6a 1012 /* Disable the DMA clock */
EricLew 9:5a860b9c8a6a 1013 AUDIO_DFSDMx_DMAx_CLK_DISABLE();
EricLew 9:5a860b9c8a6a 1014 }
EricLew 9:5a860b9c8a6a 1015
EricLew 9:5a860b9c8a6a 1016 /**
EricLew 9:5a860b9c8a6a 1017 * @brief Configures the SAI PLL clock according to the required audio frequency.
EricLew 9:5a860b9c8a6a 1018 * @param Frequency: Audio frequency.
EricLew 9:5a860b9c8a6a 1019 * @retval BSP AUDIO status
EricLew 9:5a860b9c8a6a 1020 * @note The SAI PLL input clock must be configured in the user application.
EricLew 9:5a860b9c8a6a 1021 * The SAI PLL configuration done within this function assumes that
EricLew 9:5a860b9c8a6a 1022 * the SAI PLL input clock runs at 8 MHz.
EricLew 9:5a860b9c8a6a 1023 */
EricLew 9:5a860b9c8a6a 1024 static uint8_t AUDIO_SAIPLLConfig(uint32_t Frequency)
EricLew 9:5a860b9c8a6a 1025 {
EricLew 9:5a860b9c8a6a 1026 RCC_PeriphCLKInitTypeDef RCC_ExCLKInitStruct;
EricLew 9:5a860b9c8a6a 1027
EricLew 9:5a860b9c8a6a 1028 /* Retreive actual RCC configuration */
EricLew 9:5a860b9c8a6a 1029 HAL_RCCEx_GetPeriphCLKConfig(&RCC_ExCLKInitStruct);
EricLew 9:5a860b9c8a6a 1030
EricLew 9:5a860b9c8a6a 1031 if ( (Frequency == AUDIO_FREQUENCY_11K)
EricLew 9:5a860b9c8a6a 1032 || (Frequency == AUDIO_FREQUENCY_22K)
EricLew 9:5a860b9c8a6a 1033 || (Frequency == AUDIO_FREQUENCY_44K) )
EricLew 9:5a860b9c8a6a 1034 {
EricLew 9:5a860b9c8a6a 1035 /* Configure PLLSAI prescalers */
EricLew 9:5a860b9c8a6a 1036 /* SAI clock config
EricLew 9:5a860b9c8a6a 1037 PLLSAI1_VCO= 8 Mhz * PLLSAI1N = 8 * 24 = VCO_192M
EricLew 9:5a860b9c8a6a 1038 SAI_CK_x = PLLSAI1_VCO/PLLSAI1P = 192/17 = 11.294 Mhz */
EricLew 9:5a860b9c8a6a 1039 RCC_ExCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
EricLew 9:5a860b9c8a6a 1040 RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1N = 24;
EricLew 9:5a860b9c8a6a 1041 RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1P = 17;
EricLew 9:5a860b9c8a6a 1042 RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK;
EricLew 9:5a860b9c8a6a 1043 RCC_ExCLKInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI1;
EricLew 9:5a860b9c8a6a 1044 }
EricLew 9:5a860b9c8a6a 1045 else /* AUDIO_FREQUENCY_8K, AUDIO_FREQUENCY_16K, AUDIO_FREQUENCY_48K, AUDIO_FREQUENCY_96K */
EricLew 9:5a860b9c8a6a 1046 {
EricLew 9:5a860b9c8a6a 1047 /* SAI clock config
EricLew 9:5a860b9c8a6a 1048 PLLSAI1_VCO= 8 Mhz * PLLSAI1N = 8 * 43 = VCO_344M
EricLew 9:5a860b9c8a6a 1049 SAI_CK_x = PLLSAI1_VCO/PLLSAI1P = 344/7 = 49.142 Mhz */
EricLew 9:5a860b9c8a6a 1050 RCC_ExCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI1;
EricLew 9:5a860b9c8a6a 1051 RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1N = 43;
EricLew 9:5a860b9c8a6a 1052 RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1P = 7;
EricLew 9:5a860b9c8a6a 1053 RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK;
EricLew 9:5a860b9c8a6a 1054 RCC_ExCLKInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI1;
EricLew 9:5a860b9c8a6a 1055 }
EricLew 9:5a860b9c8a6a 1056
EricLew 9:5a860b9c8a6a 1057 if (HAL_RCCEx_PeriphCLKConfig(&RCC_ExCLKInitStruct) != HAL_OK)
EricLew 9:5a860b9c8a6a 1058 {
EricLew 9:5a860b9c8a6a 1059 return AUDIO_ERROR;
EricLew 9:5a860b9c8a6a 1060 }
EricLew 9:5a860b9c8a6a 1061
EricLew 9:5a860b9c8a6a 1062 return AUDIO_OK;
EricLew 9:5a860b9c8a6a 1063 }
EricLew 9:5a860b9c8a6a 1064
EricLew 9:5a860b9c8a6a 1065
EricLew 9:5a860b9c8a6a 1066 /**
EricLew 9:5a860b9c8a6a 1067 * @brief Callback function invoked when half of the PCM samples have been
EricLew 9:5a860b9c8a6a 1068 * DM Atransfered from the DFSDM channel.
EricLew 9:5a860b9c8a6a 1069 * @param None
EricLew 9:5a860b9c8a6a 1070 * @retval None
EricLew 9:5a860b9c8a6a 1071 */
EricLew 9:5a860b9c8a6a 1072 void AudioRecord_TransferComplete_CallBack(void)
EricLew 9:5a860b9c8a6a 1073 {
EricLew 9:5a860b9c8a6a 1074 /* Toggle green LED */
EricLew 9:5a860b9c8a6a 1075 // myled = !myled;
EricLew 9:5a860b9c8a6a 1076
EricLew 9:5a860b9c8a6a 1077 RecordBufferOffset = BUFFER_OFFSET_FULL;
EricLew 9:5a860b9c8a6a 1078 }
EricLew 9:5a860b9c8a6a 1079
EricLew 9:5a860b9c8a6a 1080 /**
EricLew 9:5a860b9c8a6a 1081 * @brief Callback function invoked when all the PCM samples have been
EricLew 9:5a860b9c8a6a 1082 * DMA transfered from the DFSDM channel.
EricLew 9:5a860b9c8a6a 1083 * @param None
EricLew 9:5a860b9c8a6a 1084 * @retval None
EricLew 9:5a860b9c8a6a 1085 */
EricLew 9:5a860b9c8a6a 1086 void AudioRecord_HalfTransfer_CallBack(void)
EricLew 9:5a860b9c8a6a 1087 {
EricLew 9:5a860b9c8a6a 1088 // RecordBufferOffset = BUFFER_OFFSET_HALF;
EricLew 9:5a860b9c8a6a 1089 }
EricLew 9:5a860b9c8a6a 1090
EricLew 9:5a860b9c8a6a 1091 /**
EricLew 9:5a860b9c8a6a 1092 * @brief Callback function invoked when an error occured durint he DMA
EricLew 9:5a860b9c8a6a 1093 * transfer of the PCM samples from the DFSDM channel.
EricLew 9:5a860b9c8a6a 1094 * @param None
EricLew 9:5a860b9c8a6a 1095 * @retval None
EricLew 9:5a860b9c8a6a 1096 */
EricLew 9:5a860b9c8a6a 1097 void AudioRecord_Error_CallBack(void)
EricLew 9:5a860b9c8a6a 1098 {
EricLew 9:5a860b9c8a6a 1099 pc.printf("ERROR\r\n");
EricLew 9:5a860b9c8a6a 1100 /* Stop the program with an infinite loop */
EricLew 9:5a860b9c8a6a 1101 // Error_Handler();
EricLew 9:5a860b9c8a6a 1102 }
EricLew 9:5a860b9c8a6a 1103
EricLew 9:5a860b9c8a6a 1104
EricLew 9:5a860b9c8a6a 1105
EricLew 9:5a860b9c8a6a 1106 //uint16_t getDMAState(void)
EricLew 9:5a860b9c8a6a 1107 //{
EricLew 9:5a860b9c8a6a 1108 // return HAL_DMA_GetState(hAudioInSPI.hdmarx);
EricLew 9:5a860b9c8a6a 1109 //}
EricLew 9:5a860b9c8a6a 1110 //
EricLew 9:5a860b9c8a6a 1111 //
EricLew 9:5a860b9c8a6a 1112 //uint16_t getSPIState(void)
EricLew 9:5a860b9c8a6a 1113 //{
EricLew 9:5a860b9c8a6a 1114 // return HAL_SPI_GetState(&hAudioInSPI);
EricLew 9:5a860b9c8a6a 1115 //}
EricLew 9:5a860b9c8a6a 1116 //
EricLew 9:5a860b9c8a6a 1117 //
EricLew 9:5a860b9c8a6a 1118 //bool getSPIFlagStatus(uint16_t flag)
EricLew 9:5a860b9c8a6a 1119 //{
EricLew 9:5a860b9c8a6a 1120 // return __HAL_SPI_GET_FLAG(&hAudioInSPI, flag);
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
EricLew 9:5a860b9c8a6a 1144 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
EricLew 9:5a860b9c8a6a 1145
EricLew 9:5a860b9c8a6a 1146