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