001

Committer:
ganlikun
Date:
Sun Jun 12 14:02:44 2022 +0000
Revision:
0:13413ea9a877
00

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ganlikun 0:13413ea9a877 1 /**
ganlikun 0:13413ea9a877 2 ******************************************************************************
ganlikun 0:13413ea9a877 3 * @file stm32f4xx_hal_sai.c
ganlikun 0:13413ea9a877 4 * @author MCD Application Team
ganlikun 0:13413ea9a877 5 * @version V1.7.1
ganlikun 0:13413ea9a877 6 * @date 14-April-2017
ganlikun 0:13413ea9a877 7 * @brief SAI HAL module driver.
ganlikun 0:13413ea9a877 8 * This file provides firmware functions to manage the following
ganlikun 0:13413ea9a877 9 * functionalities of the Serial Audio Interface (SAI) peripheral:
ganlikun 0:13413ea9a877 10 * + Initialization/de-initialization functions
ganlikun 0:13413ea9a877 11 * + I/O operation functions
ganlikun 0:13413ea9a877 12 * + Peripheral Control functions
ganlikun 0:13413ea9a877 13 * + Peripheral State functions
ganlikun 0:13413ea9a877 14 *
ganlikun 0:13413ea9a877 15 @verbatim
ganlikun 0:13413ea9a877 16 ==============================================================================
ganlikun 0:13413ea9a877 17 ##### How to use this driver #####
ganlikun 0:13413ea9a877 18 ==============================================================================
ganlikun 0:13413ea9a877 19
ganlikun 0:13413ea9a877 20 [..]
ganlikun 0:13413ea9a877 21 The SAI HAL driver can be used as follows:
ganlikun 0:13413ea9a877 22
ganlikun 0:13413ea9a877 23 (#) Declare a SAI_HandleTypeDef handle structure (eg. SAI_HandleTypeDef hsai).
ganlikun 0:13413ea9a877 24 (#) Initialize the SAI low level resources by implementing the HAL_SAI_MspInit() API:
ganlikun 0:13413ea9a877 25 (##) Enable the SAI interface clock.
ganlikun 0:13413ea9a877 26 (##) SAI pins configuration:
ganlikun 0:13413ea9a877 27 (+++) Enable the clock for the SAI GPIOs.
ganlikun 0:13413ea9a877 28 (+++) Configure these SAI pins as alternate function pull-up.
ganlikun 0:13413ea9a877 29 (##) NVIC configuration if you need to use interrupt process (HAL_SAI_Transmit_IT()
ganlikun 0:13413ea9a877 30 and HAL_SAI_Receive_IT() APIs):
ganlikun 0:13413ea9a877 31 (+++) Configure the SAI interrupt priority.
ganlikun 0:13413ea9a877 32 (+++) Enable the NVIC SAI IRQ handle.
ganlikun 0:13413ea9a877 33
ganlikun 0:13413ea9a877 34 (##) DMA Configuration if you need to use DMA process (HAL_SAI_Transmit_DMA()
ganlikun 0:13413ea9a877 35 and HAL_SAI_Receive_DMA() APIs):
ganlikun 0:13413ea9a877 36 (+++) Declare a DMA handle structure for the Tx/Rx stream.
ganlikun 0:13413ea9a877 37 (+++) Enable the DMAx interface clock.
ganlikun 0:13413ea9a877 38 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
ganlikun 0:13413ea9a877 39 (+++) Configure the DMA Tx/Rx Stream.
ganlikun 0:13413ea9a877 40 (+++) Associate the initialized DMA handle to the SAI DMA Tx/Rx handle.
ganlikun 0:13413ea9a877 41 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the
ganlikun 0:13413ea9a877 42 DMA Tx/Rx Stream.
ganlikun 0:13413ea9a877 43
ganlikun 0:13413ea9a877 44 (#) The initialization can be done by two ways
ganlikun 0:13413ea9a877 45 (##) Expert mode : Initialize the structures Init, FrameInit and SlotInit and call HAL_SAI_Init().
ganlikun 0:13413ea9a877 46 (##) Simplified mode : Initialize the high part of Init Structure and call HAL_SAI_InitProtocol().
ganlikun 0:13413ea9a877 47
ganlikun 0:13413ea9a877 48 [..]
ganlikun 0:13413ea9a877 49 (@) The specific SAI interrupts (FIFO request and Overrun underrun interrupt)
ganlikun 0:13413ea9a877 50 will be managed using the macros __HAL_SAI_ENABLE_IT() and __HAL_SAI_DISABLE_IT()
ganlikun 0:13413ea9a877 51 inside the transmit and receive process.
ganlikun 0:13413ea9a877 52
ganlikun 0:13413ea9a877 53 [..]
ganlikun 0:13413ea9a877 54 (@) SAI Clock Source configuration is managed differently depending on the selected
ganlikun 0:13413ea9a877 55 STM32F4 devices :
ganlikun 0:13413ea9a877 56 (+@) For STM32F446xx devices, the configuration is managed through RCCEx_PeriphCLKConfig()
ganlikun 0:13413ea9a877 57 function in the HAL RCC drivers
ganlikun 0:13413ea9a877 58 (+@) For STM32F439xx/STM32F437xx/STM32F429xx/STM32F427xx devices, the configuration
ganlikun 0:13413ea9a877 59 is managed within HAL SAI drivers through HAL_SAI_Init() function using
ganlikun 0:13413ea9a877 60 ClockSource field of SAI_InitTypeDef structure.
ganlikun 0:13413ea9a877 61 [..]
ganlikun 0:13413ea9a877 62 (@) Make sure that either:
ganlikun 0:13413ea9a877 63 (+@) I2S PLL is configured or
ganlikun 0:13413ea9a877 64 (+@) SAI PLL is configured or
ganlikun 0:13413ea9a877 65 (+@) External clock source is configured after setting correctly
ganlikun 0:13413ea9a877 66 the define constant EXTERNAL_CLOCK_VALUE in the stm32f4xx_hal_conf.h file.
ganlikun 0:13413ea9a877 67 [..]
ganlikun 0:13413ea9a877 68 (@) In master Tx mode: enabling the audio block immediately generates the bit clock
ganlikun 0:13413ea9a877 69 for the external slaves even if there is no data in the FIFO, However FS signal
ganlikun 0:13413ea9a877 70 generation is conditioned by the presence of data in the FIFO.
ganlikun 0:13413ea9a877 71
ganlikun 0:13413ea9a877 72 [..]
ganlikun 0:13413ea9a877 73 (@) In master Rx mode: enabling the audio block immediately generates the bit clock
ganlikun 0:13413ea9a877 74 and FS signal for the external slaves.
ganlikun 0:13413ea9a877 75
ganlikun 0:13413ea9a877 76 [..]
ganlikun 0:13413ea9a877 77 (@) It is mandatory to respect the following conditions in order to avoid bad SAI behavior:
ganlikun 0:13413ea9a877 78 (+@) First bit Offset <= (SLOT size - Data size)
ganlikun 0:13413ea9a877 79 (+@) Data size <= SLOT size
ganlikun 0:13413ea9a877 80 (+@) Number of SLOT x SLOT size = Frame length
ganlikun 0:13413ea9a877 81 (+@) The number of slots should be even when SAI_FS_CHANNEL_IDENTIFICATION is selected.
ganlikun 0:13413ea9a877 82
ganlikun 0:13413ea9a877 83 [..]
ganlikun 0:13413ea9a877 84 Three operation modes are available within this driver :
ganlikun 0:13413ea9a877 85
ganlikun 0:13413ea9a877 86 *** Polling mode IO operation ***
ganlikun 0:13413ea9a877 87 =================================
ganlikun 0:13413ea9a877 88 [..]
ganlikun 0:13413ea9a877 89 (+) Send an amount of data in blocking mode using HAL_SAI_Transmit()
ganlikun 0:13413ea9a877 90 (+) Receive an amount of data in blocking mode using HAL_SAI_Receive()
ganlikun 0:13413ea9a877 91
ganlikun 0:13413ea9a877 92 *** Interrupt mode IO operation ***
ganlikun 0:13413ea9a877 93 ===================================
ganlikun 0:13413ea9a877 94 [..]
ganlikun 0:13413ea9a877 95 (+) Send an amount of data in non-blocking mode using HAL_SAI_Transmit_IT()
ganlikun 0:13413ea9a877 96 (+) At transmission end of transfer HAL_SAI_TxCpltCallback() is executed and user can
ganlikun 0:13413ea9a877 97 add his own code by customization of function pointer HAL_SAI_TxCpltCallback()
ganlikun 0:13413ea9a877 98 (+) Receive an amount of data in non-blocking mode using HAL_SAI_Receive_IT()
ganlikun 0:13413ea9a877 99 (+) At reception end of transfer HAL_SAI_RxCpltCallback() is executed and user can
ganlikun 0:13413ea9a877 100 add his own code by customization of function pointer HAL_SAI_RxCpltCallback()
ganlikun 0:13413ea9a877 101 (+) In case of flag error, HAL_SAI_ErrorCallback() function is executed and user can
ganlikun 0:13413ea9a877 102 add his own code by customization of function pointer HAL_SAI_ErrorCallback()
ganlikun 0:13413ea9a877 103
ganlikun 0:13413ea9a877 104 *** DMA mode IO operation ***
ganlikun 0:13413ea9a877 105 =============================
ganlikun 0:13413ea9a877 106 [..]
ganlikun 0:13413ea9a877 107 (+) Send an amount of data in non-blocking mode (DMA) using HAL_SAI_Transmit_DMA()
ganlikun 0:13413ea9a877 108 (+) At transmission end of transfer HAL_SAI_TxCpltCallback() is executed and user can
ganlikun 0:13413ea9a877 109 add his own code by customization of function pointer HAL_SAI_TxCpltCallback()
ganlikun 0:13413ea9a877 110 (+) Receive an amount of data in non-blocking mode (DMA) using HAL_SAI_Receive_DMA()
ganlikun 0:13413ea9a877 111 (+) At reception end of transfer HAL_SAI_RxCpltCallback() is executed and user can
ganlikun 0:13413ea9a877 112 add his own code by customization of function pointer HAL_SAI_RxCpltCallback()
ganlikun 0:13413ea9a877 113 (+) In case of flag error, HAL_SAI_ErrorCallback() function is executed and user can
ganlikun 0:13413ea9a877 114 add his own code by customization of function pointer HAL_SAI_ErrorCallback()
ganlikun 0:13413ea9a877 115 (+) Pause the DMA Transfer using HAL_SAI_DMAPause()
ganlikun 0:13413ea9a877 116 (+) Resume the DMA Transfer using HAL_SAI_DMAResume()
ganlikun 0:13413ea9a877 117 (+) Stop the DMA Transfer using HAL_SAI_DMAStop()
ganlikun 0:13413ea9a877 118
ganlikun 0:13413ea9a877 119 *** SAI HAL driver additional function list ***
ganlikun 0:13413ea9a877 120 ===============================================
ganlikun 0:13413ea9a877 121 [..]
ganlikun 0:13413ea9a877 122 Below the list the others API available SAI HAL driver :
ganlikun 0:13413ea9a877 123
ganlikun 0:13413ea9a877 124 (+) HAL_SAI_EnableTxMuteMode(): Enable the mute in tx mode
ganlikun 0:13413ea9a877 125 (+) HAL_SAI_DisableTxMuteMode(): Disable the mute in tx mode
ganlikun 0:13413ea9a877 126 (+) HAL_SAI_EnableRxMuteMode(): Enable the mute in Rx mode
ganlikun 0:13413ea9a877 127 (+) HAL_SAI_DisableRxMuteMode(): Disable the mute in Rx mode
ganlikun 0:13413ea9a877 128 (+) HAL_SAI_FlushRxFifo(): Flush the rx fifo.
ganlikun 0:13413ea9a877 129 (+) HAL_SAI_Abort(): Abort the current transfer
ganlikun 0:13413ea9a877 130
ganlikun 0:13413ea9a877 131 *** SAI HAL driver macros list ***
ganlikun 0:13413ea9a877 132 ==================================
ganlikun 0:13413ea9a877 133 [..]
ganlikun 0:13413ea9a877 134 Below the list of most used macros in SAI HAL driver :
ganlikun 0:13413ea9a877 135
ganlikun 0:13413ea9a877 136 (+) __HAL_SAI_ENABLE(): Enable the SAI peripheral
ganlikun 0:13413ea9a877 137 (+) __HAL_SAI_DISABLE(): Disable the SAI peripheral
ganlikun 0:13413ea9a877 138 (+) __HAL_SAI_ENABLE_IT(): Enable the specified SAI interrupts
ganlikun 0:13413ea9a877 139 (+) __HAL_SAI_DISABLE_IT(): Disable the specified SAI interrupts
ganlikun 0:13413ea9a877 140 (+) __HAL_SAI_GET_IT_SOURCE(): Check if the specified SAI interrupt source is
ganlikun 0:13413ea9a877 141 enabled or disabled
ganlikun 0:13413ea9a877 142 (+) __HAL_SAI_GET_FLAG(): Check whether the specified SAI flag is set or not
ganlikun 0:13413ea9a877 143
ganlikun 0:13413ea9a877 144 @endverbatim
ganlikun 0:13413ea9a877 145 ******************************************************************************
ganlikun 0:13413ea9a877 146 * @attention
ganlikun 0:13413ea9a877 147 *
ganlikun 0:13413ea9a877 148 * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
ganlikun 0:13413ea9a877 149 *
ganlikun 0:13413ea9a877 150 * Redistribution and use in source and binary forms, with or without modification,
ganlikun 0:13413ea9a877 151 * are permitted provided that the following conditions are met:
ganlikun 0:13413ea9a877 152 * 1. Redistributions of source code must retain the above copyright notice,
ganlikun 0:13413ea9a877 153 * this list of conditions and the following disclaimer.
ganlikun 0:13413ea9a877 154 * 2. Redistributions in binary form must reproduce the above copyright notice,
ganlikun 0:13413ea9a877 155 * this list of conditions and the following disclaimer in the documentation
ganlikun 0:13413ea9a877 156 * and/or other materials provided with the distribution.
ganlikun 0:13413ea9a877 157 * 3. Neither the name of STMicroelectronics nor the names of its contributors
ganlikun 0:13413ea9a877 158 * may be used to endorse or promote products derived from this software
ganlikun 0:13413ea9a877 159 * without specific prior written permission.
ganlikun 0:13413ea9a877 160 *
ganlikun 0:13413ea9a877 161 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
ganlikun 0:13413ea9a877 162 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
ganlikun 0:13413ea9a877 163 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
ganlikun 0:13413ea9a877 164 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
ganlikun 0:13413ea9a877 165 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
ganlikun 0:13413ea9a877 166 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
ganlikun 0:13413ea9a877 167 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
ganlikun 0:13413ea9a877 168 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
ganlikun 0:13413ea9a877 169 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
ganlikun 0:13413ea9a877 170 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ganlikun 0:13413ea9a877 171 *
ganlikun 0:13413ea9a877 172 ******************************************************************************
ganlikun 0:13413ea9a877 173 */
ganlikun 0:13413ea9a877 174
ganlikun 0:13413ea9a877 175 /* Includes ------------------------------------------------------------------*/
ganlikun 0:13413ea9a877 176 #include "stm32f4xx_hal.h"
ganlikun 0:13413ea9a877 177
ganlikun 0:13413ea9a877 178 /** @addtogroup STM32F4xx_HAL_Driver
ganlikun 0:13413ea9a877 179 * @{
ganlikun 0:13413ea9a877 180 */
ganlikun 0:13413ea9a877 181
ganlikun 0:13413ea9a877 182 /** @defgroup SAI SAI
ganlikun 0:13413ea9a877 183 * @brief SAI HAL module driver
ganlikun 0:13413ea9a877 184 * @{
ganlikun 0:13413ea9a877 185 */
ganlikun 0:13413ea9a877 186
ganlikun 0:13413ea9a877 187 #ifdef HAL_SAI_MODULE_ENABLED
ganlikun 0:13413ea9a877 188
ganlikun 0:13413ea9a877 189 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\
ganlikun 0:13413ea9a877 190 defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F413xx) ||\
ganlikun 0:13413ea9a877 191 defined(STM32F423xx)
ganlikun 0:13413ea9a877 192
ganlikun 0:13413ea9a877 193 /** @defgroup SAI_Private_Typedefs SAI Private Typedefs
ganlikun 0:13413ea9a877 194 * @{
ganlikun 0:13413ea9a877 195 */
ganlikun 0:13413ea9a877 196 typedef enum {
ganlikun 0:13413ea9a877 197 SAI_MODE_DMA,
ganlikun 0:13413ea9a877 198 SAI_MODE_IT
ganlikun 0:13413ea9a877 199 }SAI_ModeTypedef;
ganlikun 0:13413ea9a877 200 /**
ganlikun 0:13413ea9a877 201 * @}
ganlikun 0:13413ea9a877 202 */
ganlikun 0:13413ea9a877 203
ganlikun 0:13413ea9a877 204 /* Private define ------------------------------------------------------------*/
ganlikun 0:13413ea9a877 205
ganlikun 0:13413ea9a877 206 /** @defgroup SAI_Private_Constants SAI Private Constants
ganlikun 0:13413ea9a877 207 * @{
ganlikun 0:13413ea9a877 208 */
ganlikun 0:13413ea9a877 209 #define SAI_FIFO_SIZE 8U
ganlikun 0:13413ea9a877 210 #define SAI_DEFAULT_TIMEOUT 4U /* 4ms */
ganlikun 0:13413ea9a877 211 #define SAI_xCR2_MUTECNT_OFFSET POSITION_VAL(SAI_xCR2_MUTECNT)
ganlikun 0:13413ea9a877 212 /**
ganlikun 0:13413ea9a877 213 * @}
ganlikun 0:13413ea9a877 214 */
ganlikun 0:13413ea9a877 215
ganlikun 0:13413ea9a877 216 /* Private macro -------------------------------------------------------------*/
ganlikun 0:13413ea9a877 217 /* Private variables ---------------------------------------------------------*/
ganlikun 0:13413ea9a877 218 /* Private function prototypes -----------------------------------------------*/
ganlikun 0:13413ea9a877 219
ganlikun 0:13413ea9a877 220 /** @defgroup SAI_Private_Functions SAI Private Functions
ganlikun 0:13413ea9a877 221 * @{
ganlikun 0:13413ea9a877 222 */
ganlikun 0:13413ea9a877 223 static void SAI_FillFifo(SAI_HandleTypeDef *hsai);
ganlikun 0:13413ea9a877 224 static uint32_t SAI_InterruptFlag(SAI_HandleTypeDef *hsai, uint32_t mode);
ganlikun 0:13413ea9a877 225 static HAL_StatusTypeDef SAI_InitI2S(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot);
ganlikun 0:13413ea9a877 226 static HAL_StatusTypeDef SAI_InitPCM(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot);
ganlikun 0:13413ea9a877 227
ganlikun 0:13413ea9a877 228 static HAL_StatusTypeDef SAI_Disable(SAI_HandleTypeDef *hsai);
ganlikun 0:13413ea9a877 229 static void SAI_Transmit_IT8Bit(SAI_HandleTypeDef *hsai);
ganlikun 0:13413ea9a877 230 static void SAI_Transmit_IT16Bit(SAI_HandleTypeDef *hsai);
ganlikun 0:13413ea9a877 231 static void SAI_Transmit_IT32Bit(SAI_HandleTypeDef *hsai);
ganlikun 0:13413ea9a877 232 static void SAI_Receive_IT8Bit(SAI_HandleTypeDef *hsai);
ganlikun 0:13413ea9a877 233 static void SAI_Receive_IT16Bit(SAI_HandleTypeDef *hsai);
ganlikun 0:13413ea9a877 234 static void SAI_Receive_IT32Bit(SAI_HandleTypeDef *hsai);
ganlikun 0:13413ea9a877 235
ganlikun 0:13413ea9a877 236 static void SAI_DMATxCplt(DMA_HandleTypeDef *hdma);
ganlikun 0:13413ea9a877 237 static void SAI_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
ganlikun 0:13413ea9a877 238 static void SAI_DMARxCplt(DMA_HandleTypeDef *hdma);
ganlikun 0:13413ea9a877 239 static void SAI_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
ganlikun 0:13413ea9a877 240 static void SAI_DMAError(DMA_HandleTypeDef *hdma);
ganlikun 0:13413ea9a877 241 static void SAI_DMAAbort(DMA_HandleTypeDef *hdma);
ganlikun 0:13413ea9a877 242 /**
ganlikun 0:13413ea9a877 243 * @}
ganlikun 0:13413ea9a877 244 */
ganlikun 0:13413ea9a877 245
ganlikun 0:13413ea9a877 246 /* Exported functions ---------------------------------------------------------*/
ganlikun 0:13413ea9a877 247
ganlikun 0:13413ea9a877 248 /** @defgroup SAI_Exported_Functions SAI Exported Functions
ganlikun 0:13413ea9a877 249 * @{
ganlikun 0:13413ea9a877 250 */
ganlikun 0:13413ea9a877 251
ganlikun 0:13413ea9a877 252 /** @defgroup SAI_Exported_Functions_Group1 Initialization and de-initialization functions
ganlikun 0:13413ea9a877 253 * @brief Initialization and Configuration functions
ganlikun 0:13413ea9a877 254 *
ganlikun 0:13413ea9a877 255 @verbatim
ganlikun 0:13413ea9a877 256 ===============================================================================
ganlikun 0:13413ea9a877 257 ##### Initialization and de-initialization functions #####
ganlikun 0:13413ea9a877 258 ===============================================================================
ganlikun 0:13413ea9a877 259 [..] This subsection provides a set of functions allowing to initialize and
ganlikun 0:13413ea9a877 260 de-initialize the SAIx peripheral:
ganlikun 0:13413ea9a877 261
ganlikun 0:13413ea9a877 262 (+) User must implement HAL_SAI_MspInit() function in which he configures
ganlikun 0:13413ea9a877 263 all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
ganlikun 0:13413ea9a877 264
ganlikun 0:13413ea9a877 265 (+) Call the function HAL_SAI_Init() to configure the selected device with
ganlikun 0:13413ea9a877 266 the selected configuration:
ganlikun 0:13413ea9a877 267 (++) Mode (Master/slave TX/RX)
ganlikun 0:13413ea9a877 268 (++) Protocol
ganlikun 0:13413ea9a877 269 (++) Data Size
ganlikun 0:13413ea9a877 270 (++) MCLK Output
ganlikun 0:13413ea9a877 271 (++) Audio frequency
ganlikun 0:13413ea9a877 272 (++) FIFO Threshold
ganlikun 0:13413ea9a877 273 (++) Frame Config
ganlikun 0:13413ea9a877 274 (++) Slot Config
ganlikun 0:13413ea9a877 275
ganlikun 0:13413ea9a877 276 (+) Call the function HAL_SAI_DeInit() to restore the default configuration
ganlikun 0:13413ea9a877 277 of the selected SAI peripheral.
ganlikun 0:13413ea9a877 278
ganlikun 0:13413ea9a877 279 @endverbatim
ganlikun 0:13413ea9a877 280 * @{
ganlikun 0:13413ea9a877 281 */
ganlikun 0:13413ea9a877 282
ganlikun 0:13413ea9a877 283 /**
ganlikun 0:13413ea9a877 284 * @brief Initialize the structure FrameInit, SlotInit and the low part of
ganlikun 0:13413ea9a877 285 * Init according to the specified parameters and call the function
ganlikun 0:13413ea9a877 286 * HAL_SAI_Init to initialize the SAI block.
ganlikun 0:13413ea9a877 287 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 288 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 289 * @param protocol: one of the supported protocol @ref SAI_Protocol
ganlikun 0:13413ea9a877 290 * @param datasize: one of the supported datasize @ref SAI_Protocol_DataSize
ganlikun 0:13413ea9a877 291 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 292 * @param nbslot: Number of slot.
ganlikun 0:13413ea9a877 293 * @retval HAL status
ganlikun 0:13413ea9a877 294 */
ganlikun 0:13413ea9a877 295 HAL_StatusTypeDef HAL_SAI_InitProtocol(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot)
ganlikun 0:13413ea9a877 296 {
ganlikun 0:13413ea9a877 297 HAL_StatusTypeDef status = HAL_OK;
ganlikun 0:13413ea9a877 298
ganlikun 0:13413ea9a877 299 /* Check the parameters */
ganlikun 0:13413ea9a877 300 assert_param(IS_SAI_SUPPORTED_PROTOCOL(protocol));
ganlikun 0:13413ea9a877 301 assert_param(IS_SAI_PROTOCOL_DATASIZE(datasize));
ganlikun 0:13413ea9a877 302
ganlikun 0:13413ea9a877 303 switch(protocol)
ganlikun 0:13413ea9a877 304 {
ganlikun 0:13413ea9a877 305 case SAI_I2S_STANDARD :
ganlikun 0:13413ea9a877 306 case SAI_I2S_MSBJUSTIFIED :
ganlikun 0:13413ea9a877 307 case SAI_I2S_LSBJUSTIFIED :
ganlikun 0:13413ea9a877 308 status = SAI_InitI2S(hsai, protocol, datasize, nbslot);
ganlikun 0:13413ea9a877 309 break;
ganlikun 0:13413ea9a877 310 case SAI_PCM_LONG :
ganlikun 0:13413ea9a877 311 case SAI_PCM_SHORT :
ganlikun 0:13413ea9a877 312 status = SAI_InitPCM(hsai, protocol, datasize, nbslot);
ganlikun 0:13413ea9a877 313 break;
ganlikun 0:13413ea9a877 314 default :
ganlikun 0:13413ea9a877 315 status = HAL_ERROR;
ganlikun 0:13413ea9a877 316 break;
ganlikun 0:13413ea9a877 317 }
ganlikun 0:13413ea9a877 318
ganlikun 0:13413ea9a877 319 if(status == HAL_OK)
ganlikun 0:13413ea9a877 320 {
ganlikun 0:13413ea9a877 321 status = HAL_SAI_Init(hsai);
ganlikun 0:13413ea9a877 322 }
ganlikun 0:13413ea9a877 323
ganlikun 0:13413ea9a877 324 return status;
ganlikun 0:13413ea9a877 325 }
ganlikun 0:13413ea9a877 326
ganlikun 0:13413ea9a877 327 /**
ganlikun 0:13413ea9a877 328 * @brief Initialize the SAI according to the specified parameters.
ganlikun 0:13413ea9a877 329 * in the SAI_InitTypeDef structure and initialize the associated handle.
ganlikun 0:13413ea9a877 330 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 331 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 332 * @retval HAL status
ganlikun 0:13413ea9a877 333 */
ganlikun 0:13413ea9a877 334 HAL_StatusTypeDef HAL_SAI_Init(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 335 {
ganlikun 0:13413ea9a877 336 uint32_t tmpregisterGCR = 0U;
ganlikun 0:13413ea9a877 337
ganlikun 0:13413ea9a877 338 /* This variable used to store the SAI_CK_x (value in Hz) */
ganlikun 0:13413ea9a877 339 uint32_t freq = 0U;
ganlikun 0:13413ea9a877 340
ganlikun 0:13413ea9a877 341 /* This variable is used to compute CKSTR bits of SAI CR1 according to
ganlikun 0:13413ea9a877 342 ClockStrobing and AudioMode fields */
ganlikun 0:13413ea9a877 343 uint32_t ckstr_bits = 0U;
ganlikun 0:13413ea9a877 344 uint32_t syncen_bits = 0U;
ganlikun 0:13413ea9a877 345
ganlikun 0:13413ea9a877 346 /* Check the SAI handle allocation */
ganlikun 0:13413ea9a877 347 if(hsai == NULL)
ganlikun 0:13413ea9a877 348 {
ganlikun 0:13413ea9a877 349 return HAL_ERROR;
ganlikun 0:13413ea9a877 350 }
ganlikun 0:13413ea9a877 351
ganlikun 0:13413ea9a877 352 /* check the instance */
ganlikun 0:13413ea9a877 353 assert_param(IS_SAI_ALL_INSTANCE(hsai->Instance));
ganlikun 0:13413ea9a877 354
ganlikun 0:13413ea9a877 355 /* Check the SAI Block parameters */
ganlikun 0:13413ea9a877 356 assert_param(IS_SAI_AUDIO_FREQUENCY(hsai->Init.AudioFrequency));
ganlikun 0:13413ea9a877 357 assert_param(IS_SAI_BLOCK_PROTOCOL(hsai->Init.Protocol));
ganlikun 0:13413ea9a877 358 assert_param(IS_SAI_BLOCK_MODE(hsai->Init.AudioMode));
ganlikun 0:13413ea9a877 359 assert_param(IS_SAI_BLOCK_SYNCEXT(hsai->Init.SynchroExt));
ganlikun 0:13413ea9a877 360 assert_param(IS_SAI_BLOCK_DATASIZE(hsai->Init.DataSize));
ganlikun 0:13413ea9a877 361 assert_param(IS_SAI_BLOCK_FIRST_BIT(hsai->Init.FirstBit));
ganlikun 0:13413ea9a877 362 assert_param(IS_SAI_BLOCK_CLOCK_STROBING(hsai->Init.ClockStrobing));
ganlikun 0:13413ea9a877 363 assert_param(IS_SAI_BLOCK_SYNCHRO(hsai->Init.Synchro));
ganlikun 0:13413ea9a877 364 assert_param(IS_SAI_BLOCK_OUTPUT_DRIVE(hsai->Init.OutputDrive));
ganlikun 0:13413ea9a877 365 assert_param(IS_SAI_BLOCK_NODIVIDER(hsai->Init.NoDivider));
ganlikun 0:13413ea9a877 366 assert_param(IS_SAI_BLOCK_FIFO_THRESHOLD(hsai->Init.FIFOThreshold));
ganlikun 0:13413ea9a877 367 assert_param(IS_SAI_MONO_STEREO_MODE(hsai->Init.MonoStereoMode));
ganlikun 0:13413ea9a877 368 assert_param(IS_SAI_BLOCK_COMPANDING_MODE(hsai->Init.CompandingMode));
ganlikun 0:13413ea9a877 369 assert_param(IS_SAI_BLOCK_TRISTATE_MANAGEMENT(hsai->Init.TriState));
ganlikun 0:13413ea9a877 370
ganlikun 0:13413ea9a877 371 /* Check the SAI Block Frame parameters */
ganlikun 0:13413ea9a877 372 assert_param(IS_SAI_BLOCK_FRAME_LENGTH(hsai->FrameInit.FrameLength));
ganlikun 0:13413ea9a877 373 assert_param(IS_SAI_BLOCK_ACTIVE_FRAME(hsai->FrameInit.ActiveFrameLength));
ganlikun 0:13413ea9a877 374 assert_param(IS_SAI_BLOCK_FS_DEFINITION(hsai->FrameInit.FSDefinition));
ganlikun 0:13413ea9a877 375 assert_param(IS_SAI_BLOCK_FS_POLARITY(hsai->FrameInit.FSPolarity));
ganlikun 0:13413ea9a877 376 assert_param(IS_SAI_BLOCK_FS_OFFSET(hsai->FrameInit.FSOffset));
ganlikun 0:13413ea9a877 377
ganlikun 0:13413ea9a877 378 /* Check the SAI Block Slot parameters */
ganlikun 0:13413ea9a877 379 assert_param(IS_SAI_BLOCK_FIRSTBIT_OFFSET(hsai->SlotInit.FirstBitOffset));
ganlikun 0:13413ea9a877 380 assert_param(IS_SAI_BLOCK_SLOT_SIZE(hsai->SlotInit.SlotSize));
ganlikun 0:13413ea9a877 381 assert_param(IS_SAI_BLOCK_SLOT_NUMBER(hsai->SlotInit.SlotNumber));
ganlikun 0:13413ea9a877 382 assert_param(IS_SAI_SLOT_ACTIVE(hsai->SlotInit.SlotActive));
ganlikun 0:13413ea9a877 383
ganlikun 0:13413ea9a877 384 if(hsai->State == HAL_SAI_STATE_RESET)
ganlikun 0:13413ea9a877 385 {
ganlikun 0:13413ea9a877 386 /* Allocate lock resource and initialize it */
ganlikun 0:13413ea9a877 387 hsai->Lock = HAL_UNLOCKED;
ganlikun 0:13413ea9a877 388
ganlikun 0:13413ea9a877 389 /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
ganlikun 0:13413ea9a877 390 HAL_SAI_MspInit(hsai);
ganlikun 0:13413ea9a877 391 }
ganlikun 0:13413ea9a877 392
ganlikun 0:13413ea9a877 393 hsai->State = HAL_SAI_STATE_BUSY;
ganlikun 0:13413ea9a877 394
ganlikun 0:13413ea9a877 395 /* Disable the selected SAI peripheral */
ganlikun 0:13413ea9a877 396 SAI_Disable(hsai);
ganlikun 0:13413ea9a877 397
ganlikun 0:13413ea9a877 398 /* SAI Block Synchro Configuration -----------------------------------------*/
ganlikun 0:13413ea9a877 399 SAI_BlockSynchroConfig(hsai);
ganlikun 0:13413ea9a877 400
ganlikun 0:13413ea9a877 401 /* Configure Master Clock using the following formula :
ganlikun 0:13413ea9a877 402 MCLK_x = SAI_CK_x / (MCKDIV[3:0] * 2) with MCLK_x = 256 * FS
ganlikun 0:13413ea9a877 403 FS = SAI_CK_x / (MCKDIV[3:0] * 2) * 256
ganlikun 0:13413ea9a877 404 MCKDIV[3:0] = SAI_CK_x / FS * 512 */
ganlikun 0:13413ea9a877 405 if(hsai->Init.AudioFrequency != SAI_AUDIO_FREQUENCY_MCKDIV)
ganlikun 0:13413ea9a877 406 {
ganlikun 0:13413ea9a877 407 /* Get SAI clock source based on Source clock selection from RCC */
ganlikun 0:13413ea9a877 408 freq = SAI_GetInputClock(hsai);
ganlikun 0:13413ea9a877 409
ganlikun 0:13413ea9a877 410 /* (saiclocksource x 10) to keep Significant digits */
ganlikun 0:13413ea9a877 411 tmpregisterGCR = (((freq * 10U) / ((hsai->Init.AudioFrequency) * 512U)));
ganlikun 0:13413ea9a877 412
ganlikun 0:13413ea9a877 413 hsai->Init.Mckdiv = tmpregisterGCR / 10U;
ganlikun 0:13413ea9a877 414
ganlikun 0:13413ea9a877 415 /* Round result to the nearest integer */
ganlikun 0:13413ea9a877 416 if((tmpregisterGCR % 10U) > 8U)
ganlikun 0:13413ea9a877 417 {
ganlikun 0:13413ea9a877 418 hsai->Init.Mckdiv+= 1U;
ganlikun 0:13413ea9a877 419 }
ganlikun 0:13413ea9a877 420 }
ganlikun 0:13413ea9a877 421
ganlikun 0:13413ea9a877 422 /* Compute CKSTR bits of SAI CR1 according to ClockStrobing and AudioMode */
ganlikun 0:13413ea9a877 423 if((hsai->Init.AudioMode == SAI_MODEMASTER_TX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX))
ganlikun 0:13413ea9a877 424 {
ganlikun 0:13413ea9a877 425 ckstr_bits = (hsai->Init.ClockStrobing == SAI_CLOCKSTROBING_RISINGEDGE) ? 0U: SAI_xCR1_CKSTR;
ganlikun 0:13413ea9a877 426 }
ganlikun 0:13413ea9a877 427 else
ganlikun 0:13413ea9a877 428 {
ganlikun 0:13413ea9a877 429 ckstr_bits = (hsai->Init.ClockStrobing == SAI_CLOCKSTROBING_RISINGEDGE) ? SAI_xCR1_CKSTR: 0U;
ganlikun 0:13413ea9a877 430 }
ganlikun 0:13413ea9a877 431
ganlikun 0:13413ea9a877 432 /* SAI Block Configuration -------------------------------------------------*/
ganlikun 0:13413ea9a877 433 switch(hsai->Init.Synchro)
ganlikun 0:13413ea9a877 434 {
ganlikun 0:13413ea9a877 435 case SAI_ASYNCHRONOUS :
ganlikun 0:13413ea9a877 436 {
ganlikun 0:13413ea9a877 437 syncen_bits = 0U;
ganlikun 0:13413ea9a877 438 }
ganlikun 0:13413ea9a877 439 break;
ganlikun 0:13413ea9a877 440 case SAI_SYNCHRONOUS :
ganlikun 0:13413ea9a877 441 {
ganlikun 0:13413ea9a877 442 syncen_bits = SAI_xCR1_SYNCEN_0;
ganlikun 0:13413ea9a877 443 }
ganlikun 0:13413ea9a877 444 break;
ganlikun 0:13413ea9a877 445 case SAI_SYNCHRONOUS_EXT_SAI1 :
ganlikun 0:13413ea9a877 446 case SAI_SYNCHRONOUS_EXT_SAI2 :
ganlikun 0:13413ea9a877 447 {
ganlikun 0:13413ea9a877 448 syncen_bits = SAI_xCR1_SYNCEN_1;
ganlikun 0:13413ea9a877 449 }
ganlikun 0:13413ea9a877 450 break;
ganlikun 0:13413ea9a877 451 default:
ganlikun 0:13413ea9a877 452 break;
ganlikun 0:13413ea9a877 453 }
ganlikun 0:13413ea9a877 454 /* SAI CR1 Configuration */
ganlikun 0:13413ea9a877 455 hsai->Instance->CR1 &= ~(SAI_xCR1_MODE | SAI_xCR1_PRTCFG | SAI_xCR1_DS | \
ganlikun 0:13413ea9a877 456 SAI_xCR1_LSBFIRST | SAI_xCR1_CKSTR | SAI_xCR1_SYNCEN |\
ganlikun 0:13413ea9a877 457 SAI_xCR1_MONO | SAI_xCR1_OUTDRIV | SAI_xCR1_DMAEN | \
ganlikun 0:13413ea9a877 458 SAI_xCR1_NODIV | SAI_xCR1_MCKDIV);
ganlikun 0:13413ea9a877 459
ganlikun 0:13413ea9a877 460 hsai->Instance->CR1 |= (hsai->Init.AudioMode | hsai->Init.Protocol | \
ganlikun 0:13413ea9a877 461 hsai->Init.DataSize | hsai->Init.FirstBit | \
ganlikun 0:13413ea9a877 462 ckstr_bits | syncen_bits | \
ganlikun 0:13413ea9a877 463 hsai->Init.MonoStereoMode | hsai->Init.OutputDrive | \
ganlikun 0:13413ea9a877 464 hsai->Init.NoDivider | (hsai->Init.Mckdiv << 20U));
ganlikun 0:13413ea9a877 465
ganlikun 0:13413ea9a877 466 /* SAI CR2 Configuration */
ganlikun 0:13413ea9a877 467 hsai->Instance->CR2 &= ~(SAI_xCR2_FTH | SAI_xCR2_FFLUSH | SAI_xCR2_COMP | SAI_xCR2_CPL);
ganlikun 0:13413ea9a877 468 hsai->Instance->CR2 |= (hsai->Init.FIFOThreshold | hsai->Init.CompandingMode | hsai->Init.TriState);
ganlikun 0:13413ea9a877 469
ganlikun 0:13413ea9a877 470 /* SAI Frame Configuration -----------------------------------------*/
ganlikun 0:13413ea9a877 471 hsai->Instance->FRCR&=(~(SAI_xFRCR_FRL | SAI_xFRCR_FSALL | SAI_xFRCR_FSDEF | \
ganlikun 0:13413ea9a877 472 SAI_xFRCR_FSPOL | SAI_xFRCR_FSOFF));
ganlikun 0:13413ea9a877 473 hsai->Instance->FRCR|=((hsai->FrameInit.FrameLength - 1U) |
ganlikun 0:13413ea9a877 474 hsai->FrameInit.FSOffset |
ganlikun 0:13413ea9a877 475 hsai->FrameInit.FSDefinition |
ganlikun 0:13413ea9a877 476 hsai->FrameInit.FSPolarity |
ganlikun 0:13413ea9a877 477 ((hsai->FrameInit.ActiveFrameLength - 1U) << 8U));
ganlikun 0:13413ea9a877 478
ganlikun 0:13413ea9a877 479 /* SAI Block_x SLOT Configuration ------------------------------------------*/
ganlikun 0:13413ea9a877 480 /* This register has no meaning in AC 97 and SPDIF audio protocol */
ganlikun 0:13413ea9a877 481 hsai->Instance->SLOTR &= ~(SAI_xSLOTR_FBOFF | SAI_xSLOTR_SLOTSZ | \
ganlikun 0:13413ea9a877 482 SAI_xSLOTR_NBSLOT | SAI_xSLOTR_SLOTEN );
ganlikun 0:13413ea9a877 483
ganlikun 0:13413ea9a877 484 hsai->Instance->SLOTR |= hsai->SlotInit.FirstBitOffset | hsai->SlotInit.SlotSize | \
ganlikun 0:13413ea9a877 485 (hsai->SlotInit.SlotActive << 16U) | ((hsai->SlotInit.SlotNumber - 1U) << 8U);
ganlikun 0:13413ea9a877 486
ganlikun 0:13413ea9a877 487 /* Initialize the error code */
ganlikun 0:13413ea9a877 488 hsai->ErrorCode = HAL_SAI_ERROR_NONE;
ganlikun 0:13413ea9a877 489
ganlikun 0:13413ea9a877 490 /* Initialize the SAI state */
ganlikun 0:13413ea9a877 491 hsai->State= HAL_SAI_STATE_READY;
ganlikun 0:13413ea9a877 492
ganlikun 0:13413ea9a877 493 /* Release Lock */
ganlikun 0:13413ea9a877 494 __HAL_UNLOCK(hsai);
ganlikun 0:13413ea9a877 495
ganlikun 0:13413ea9a877 496 return HAL_OK;
ganlikun 0:13413ea9a877 497 }
ganlikun 0:13413ea9a877 498
ganlikun 0:13413ea9a877 499 /**
ganlikun 0:13413ea9a877 500 * @brief DeInitialize the SAI peripheral.
ganlikun 0:13413ea9a877 501 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 502 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 503 * @retval HAL status
ganlikun 0:13413ea9a877 504 */
ganlikun 0:13413ea9a877 505 HAL_StatusTypeDef HAL_SAI_DeInit(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 506 {
ganlikun 0:13413ea9a877 507 /* Check the SAI handle allocation */
ganlikun 0:13413ea9a877 508 if(hsai == NULL)
ganlikun 0:13413ea9a877 509 {
ganlikun 0:13413ea9a877 510 return HAL_ERROR;
ganlikun 0:13413ea9a877 511 }
ganlikun 0:13413ea9a877 512
ganlikun 0:13413ea9a877 513 hsai->State = HAL_SAI_STATE_BUSY;
ganlikun 0:13413ea9a877 514
ganlikun 0:13413ea9a877 515 /* Disabled All interrupt and clear all the flag */
ganlikun 0:13413ea9a877 516 hsai->Instance->IMR = 0U;
ganlikun 0:13413ea9a877 517 hsai->Instance->CLRFR = 0xFFFFFFFFU;
ganlikun 0:13413ea9a877 518
ganlikun 0:13413ea9a877 519 /* Disable the SAI */
ganlikun 0:13413ea9a877 520 SAI_Disable(hsai);
ganlikun 0:13413ea9a877 521
ganlikun 0:13413ea9a877 522 /* Flush the fifo */
ganlikun 0:13413ea9a877 523 SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH);
ganlikun 0:13413ea9a877 524
ganlikun 0:13413ea9a877 525 /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */
ganlikun 0:13413ea9a877 526 HAL_SAI_MspDeInit(hsai);
ganlikun 0:13413ea9a877 527
ganlikun 0:13413ea9a877 528 /* Initialize the error code */
ganlikun 0:13413ea9a877 529 hsai->ErrorCode = HAL_SAI_ERROR_NONE;
ganlikun 0:13413ea9a877 530
ganlikun 0:13413ea9a877 531 /* Initialize the SAI state */
ganlikun 0:13413ea9a877 532 hsai->State = HAL_SAI_STATE_RESET;
ganlikun 0:13413ea9a877 533
ganlikun 0:13413ea9a877 534 /* Release Lock */
ganlikun 0:13413ea9a877 535 __HAL_UNLOCK(hsai);
ganlikun 0:13413ea9a877 536
ganlikun 0:13413ea9a877 537 return HAL_OK;
ganlikun 0:13413ea9a877 538 }
ganlikun 0:13413ea9a877 539
ganlikun 0:13413ea9a877 540 /**
ganlikun 0:13413ea9a877 541 * @brief Initialize the SAI MSP.
ganlikun 0:13413ea9a877 542 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 543 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 544 * @retval None
ganlikun 0:13413ea9a877 545 */
ganlikun 0:13413ea9a877 546 __weak void HAL_SAI_MspInit(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 547 {
ganlikun 0:13413ea9a877 548 /* Prevent unused argument(s) compilation warning */
ganlikun 0:13413ea9a877 549 UNUSED(hsai);
ganlikun 0:13413ea9a877 550
ganlikun 0:13413ea9a877 551 /* NOTE : This function should not be modified, when the callback is needed,
ganlikun 0:13413ea9a877 552 the HAL_SAI_MspInit could be implemented in the user file
ganlikun 0:13413ea9a877 553 */
ganlikun 0:13413ea9a877 554 }
ganlikun 0:13413ea9a877 555
ganlikun 0:13413ea9a877 556 /**
ganlikun 0:13413ea9a877 557 * @brief DeInitialize the SAI MSP.
ganlikun 0:13413ea9a877 558 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 559 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 560 * @retval None
ganlikun 0:13413ea9a877 561 */
ganlikun 0:13413ea9a877 562 __weak void HAL_SAI_MspDeInit(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 563 {
ganlikun 0:13413ea9a877 564 /* Prevent unused argument(s) compilation warning */
ganlikun 0:13413ea9a877 565 UNUSED(hsai);
ganlikun 0:13413ea9a877 566
ganlikun 0:13413ea9a877 567 /* NOTE : This function should not be modified, when the callback is needed,
ganlikun 0:13413ea9a877 568 the HAL_SAI_MspDeInit could be implemented in the user file
ganlikun 0:13413ea9a877 569 */
ganlikun 0:13413ea9a877 570 }
ganlikun 0:13413ea9a877 571
ganlikun 0:13413ea9a877 572 /**
ganlikun 0:13413ea9a877 573 * @}
ganlikun 0:13413ea9a877 574 */
ganlikun 0:13413ea9a877 575
ganlikun 0:13413ea9a877 576 /** @defgroup SAI_Exported_Functions_Group2 IO operation functions
ganlikun 0:13413ea9a877 577 * @brief Data transfers functions
ganlikun 0:13413ea9a877 578 *
ganlikun 0:13413ea9a877 579 @verbatim
ganlikun 0:13413ea9a877 580 ==============================================================================
ganlikun 0:13413ea9a877 581 ##### IO operation functions #####
ganlikun 0:13413ea9a877 582 ==============================================================================
ganlikun 0:13413ea9a877 583 [..]
ganlikun 0:13413ea9a877 584 This subsection provides a set of functions allowing to manage the SAI data
ganlikun 0:13413ea9a877 585 transfers.
ganlikun 0:13413ea9a877 586
ganlikun 0:13413ea9a877 587 (+) There are two modes of transfer:
ganlikun 0:13413ea9a877 588 (++) Blocking mode : The communication is performed in the polling mode.
ganlikun 0:13413ea9a877 589 The status of all data processing is returned by the same function
ganlikun 0:13413ea9a877 590 after finishing transfer.
ganlikun 0:13413ea9a877 591 (++) No-Blocking mode : The communication is performed using Interrupts
ganlikun 0:13413ea9a877 592 or DMA. These functions return the status of the transfer startup.
ganlikun 0:13413ea9a877 593 The end of the data processing will be indicated through the
ganlikun 0:13413ea9a877 594 dedicated SAI IRQ when using Interrupt mode or the DMA IRQ when
ganlikun 0:13413ea9a877 595 using DMA mode.
ganlikun 0:13413ea9a877 596
ganlikun 0:13413ea9a877 597 (+) Blocking mode functions are :
ganlikun 0:13413ea9a877 598 (++) HAL_SAI_Transmit()
ganlikun 0:13413ea9a877 599 (++) HAL_SAI_Receive()
ganlikun 0:13413ea9a877 600 (++) HAL_SAI_TransmitReceive()
ganlikun 0:13413ea9a877 601
ganlikun 0:13413ea9a877 602 (+) Non Blocking mode functions with Interrupt are :
ganlikun 0:13413ea9a877 603 (++) HAL_SAI_Transmit_IT()
ganlikun 0:13413ea9a877 604 (++) HAL_SAI_Receive_IT()
ganlikun 0:13413ea9a877 605 (++) HAL_SAI_TransmitReceive_IT()
ganlikun 0:13413ea9a877 606
ganlikun 0:13413ea9a877 607 (+) Non Blocking mode functions with DMA are :
ganlikun 0:13413ea9a877 608 (++) HAL_SAI_Transmit_DMA()
ganlikun 0:13413ea9a877 609 (++) HAL_SAI_Receive_DMA()
ganlikun 0:13413ea9a877 610 (++) HAL_SAI_TransmitReceive_DMA()
ganlikun 0:13413ea9a877 611
ganlikun 0:13413ea9a877 612 (+) A set of Transfer Complete Callbacks are provided in non Blocking mode:
ganlikun 0:13413ea9a877 613 (++) HAL_SAI_TxCpltCallback()
ganlikun 0:13413ea9a877 614 (++) HAL_SAI_RxCpltCallback()
ganlikun 0:13413ea9a877 615 (++) HAL_SAI_ErrorCallback()
ganlikun 0:13413ea9a877 616
ganlikun 0:13413ea9a877 617 @endverbatim
ganlikun 0:13413ea9a877 618 * @{
ganlikun 0:13413ea9a877 619 */
ganlikun 0:13413ea9a877 620
ganlikun 0:13413ea9a877 621 /**
ganlikun 0:13413ea9a877 622 * @brief Transmit an amount of data in blocking mode.
ganlikun 0:13413ea9a877 623 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 624 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 625 * @param pData: Pointer to data buffer
ganlikun 0:13413ea9a877 626 * @param Size: Amount of data to be sent
ganlikun 0:13413ea9a877 627 * @param Timeout: Timeout duration
ganlikun 0:13413ea9a877 628 * @retval HAL status
ganlikun 0:13413ea9a877 629 */
ganlikun 0:13413ea9a877 630 HAL_StatusTypeDef HAL_SAI_Transmit(SAI_HandleTypeDef *hsai, uint8_t* pData, uint16_t Size, uint32_t Timeout)
ganlikun 0:13413ea9a877 631 {
ganlikun 0:13413ea9a877 632 uint32_t tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 633
ganlikun 0:13413ea9a877 634 if((pData == NULL ) || (Size == 0))
ganlikun 0:13413ea9a877 635 {
ganlikun 0:13413ea9a877 636 return HAL_ERROR;
ganlikun 0:13413ea9a877 637 }
ganlikun 0:13413ea9a877 638
ganlikun 0:13413ea9a877 639 if(hsai->State == HAL_SAI_STATE_READY)
ganlikun 0:13413ea9a877 640 {
ganlikun 0:13413ea9a877 641 /* Process Locked */
ganlikun 0:13413ea9a877 642 __HAL_LOCK(hsai);
ganlikun 0:13413ea9a877 643
ganlikun 0:13413ea9a877 644 hsai->XferSize = Size;
ganlikun 0:13413ea9a877 645 hsai->XferCount = Size;
ganlikun 0:13413ea9a877 646 hsai->pBuffPtr = pData;
ganlikun 0:13413ea9a877 647 hsai->State = HAL_SAI_STATE_BUSY_TX;
ganlikun 0:13413ea9a877 648 hsai->ErrorCode = HAL_SAI_ERROR_NONE;
ganlikun 0:13413ea9a877 649
ganlikun 0:13413ea9a877 650 /* Check if the SAI is already enabled */
ganlikun 0:13413ea9a877 651 if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET)
ganlikun 0:13413ea9a877 652 {
ganlikun 0:13413ea9a877 653 /* fill the fifo with data before to enabled the SAI */
ganlikun 0:13413ea9a877 654 SAI_FillFifo(hsai);
ganlikun 0:13413ea9a877 655 /* Enable SAI peripheral */
ganlikun 0:13413ea9a877 656 __HAL_SAI_ENABLE(hsai);
ganlikun 0:13413ea9a877 657 }
ganlikun 0:13413ea9a877 658
ganlikun 0:13413ea9a877 659 while(hsai->XferCount > 0U)
ganlikun 0:13413ea9a877 660 {
ganlikun 0:13413ea9a877 661 /* Write data if the FIFO is not full */
ganlikun 0:13413ea9a877 662 if((hsai->Instance->SR & SAI_xSR_FLVL) != SAI_FIFOSTATUS_FULL)
ganlikun 0:13413ea9a877 663 {
ganlikun 0:13413ea9a877 664 if((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
ganlikun 0:13413ea9a877 665 {
ganlikun 0:13413ea9a877 666 hsai->Instance->DR = (*hsai->pBuffPtr++);
ganlikun 0:13413ea9a877 667 }
ganlikun 0:13413ea9a877 668 else if(hsai->Init.DataSize <= SAI_DATASIZE_16)
ganlikun 0:13413ea9a877 669 {
ganlikun 0:13413ea9a877 670 hsai->Instance->DR = *((uint16_t *)hsai->pBuffPtr);
ganlikun 0:13413ea9a877 671 hsai->pBuffPtr+= 2U;
ganlikun 0:13413ea9a877 672 }
ganlikun 0:13413ea9a877 673 else
ganlikun 0:13413ea9a877 674 {
ganlikun 0:13413ea9a877 675 hsai->Instance->DR = *((uint32_t *)hsai->pBuffPtr);
ganlikun 0:13413ea9a877 676 hsai->pBuffPtr+= 4U;
ganlikun 0:13413ea9a877 677 }
ganlikun 0:13413ea9a877 678 hsai->XferCount--;
ganlikun 0:13413ea9a877 679 }
ganlikun 0:13413ea9a877 680 else
ganlikun 0:13413ea9a877 681 {
ganlikun 0:13413ea9a877 682 /* Check for the Timeout */
ganlikun 0:13413ea9a877 683 if((Timeout != HAL_MAX_DELAY) && ((Timeout == 0U)||((HAL_GetTick() - tickstart) > Timeout)))
ganlikun 0:13413ea9a877 684 {
ganlikun 0:13413ea9a877 685 /* Update error code */
ganlikun 0:13413ea9a877 686 hsai->ErrorCode |= HAL_SAI_ERROR_TIMEOUT;
ganlikun 0:13413ea9a877 687
ganlikun 0:13413ea9a877 688 /* Clear all the flags */
ganlikun 0:13413ea9a877 689 hsai->Instance->CLRFR = 0xFFFFFFFFU;
ganlikun 0:13413ea9a877 690
ganlikun 0:13413ea9a877 691 /* Disable SAI peripheral */
ganlikun 0:13413ea9a877 692 SAI_Disable(hsai);
ganlikun 0:13413ea9a877 693
ganlikun 0:13413ea9a877 694 /* Flush the fifo */
ganlikun 0:13413ea9a877 695 SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH);
ganlikun 0:13413ea9a877 696
ganlikun 0:13413ea9a877 697 /* Change the SAI state */
ganlikun 0:13413ea9a877 698 hsai->State = HAL_SAI_STATE_READY;
ganlikun 0:13413ea9a877 699
ganlikun 0:13413ea9a877 700 /* Process Unlocked */
ganlikun 0:13413ea9a877 701 __HAL_UNLOCK(hsai);
ganlikun 0:13413ea9a877 702
ganlikun 0:13413ea9a877 703 return HAL_ERROR;
ganlikun 0:13413ea9a877 704 }
ganlikun 0:13413ea9a877 705 }
ganlikun 0:13413ea9a877 706 }
ganlikun 0:13413ea9a877 707
ganlikun 0:13413ea9a877 708 hsai->State = HAL_SAI_STATE_READY;
ganlikun 0:13413ea9a877 709
ganlikun 0:13413ea9a877 710 /* Process Unlocked */
ganlikun 0:13413ea9a877 711 __HAL_UNLOCK(hsai);
ganlikun 0:13413ea9a877 712
ganlikun 0:13413ea9a877 713 return HAL_OK;
ganlikun 0:13413ea9a877 714 }
ganlikun 0:13413ea9a877 715 else
ganlikun 0:13413ea9a877 716 {
ganlikun 0:13413ea9a877 717 return HAL_BUSY;
ganlikun 0:13413ea9a877 718 }
ganlikun 0:13413ea9a877 719 }
ganlikun 0:13413ea9a877 720
ganlikun 0:13413ea9a877 721 /**
ganlikun 0:13413ea9a877 722 * @brief Receive an amount of data in blocking mode.
ganlikun 0:13413ea9a877 723 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 724 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 725 * @param pData: Pointer to data buffer
ganlikun 0:13413ea9a877 726 * @param Size: Amount of data to be received
ganlikun 0:13413ea9a877 727 * @param Timeout: Timeout duration
ganlikun 0:13413ea9a877 728 * @retval HAL status
ganlikun 0:13413ea9a877 729 */
ganlikun 0:13413ea9a877 730 HAL_StatusTypeDef HAL_SAI_Receive(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size, uint32_t Timeout)
ganlikun 0:13413ea9a877 731 {
ganlikun 0:13413ea9a877 732 uint32_t tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 733
ganlikun 0:13413ea9a877 734 if((pData == NULL ) || (Size == 0))
ganlikun 0:13413ea9a877 735 {
ganlikun 0:13413ea9a877 736 return HAL_ERROR;
ganlikun 0:13413ea9a877 737 }
ganlikun 0:13413ea9a877 738
ganlikun 0:13413ea9a877 739 if(hsai->State == HAL_SAI_STATE_READY)
ganlikun 0:13413ea9a877 740 {
ganlikun 0:13413ea9a877 741 /* Process Locked */
ganlikun 0:13413ea9a877 742 __HAL_LOCK(hsai);
ganlikun 0:13413ea9a877 743
ganlikun 0:13413ea9a877 744 hsai->pBuffPtr = pData;
ganlikun 0:13413ea9a877 745 hsai->XferSize = Size;
ganlikun 0:13413ea9a877 746 hsai->XferCount = Size;
ganlikun 0:13413ea9a877 747 hsai->State = HAL_SAI_STATE_BUSY_RX;
ganlikun 0:13413ea9a877 748 hsai->ErrorCode = HAL_SAI_ERROR_NONE;
ganlikun 0:13413ea9a877 749
ganlikun 0:13413ea9a877 750 /* Check if the SAI is already enabled */
ganlikun 0:13413ea9a877 751 if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET)
ganlikun 0:13413ea9a877 752 {
ganlikun 0:13413ea9a877 753 /* Enable SAI peripheral */
ganlikun 0:13413ea9a877 754 __HAL_SAI_ENABLE(hsai);
ganlikun 0:13413ea9a877 755 }
ganlikun 0:13413ea9a877 756
ganlikun 0:13413ea9a877 757 /* Receive data */
ganlikun 0:13413ea9a877 758 while(hsai->XferCount > 0U)
ganlikun 0:13413ea9a877 759 {
ganlikun 0:13413ea9a877 760 if((hsai->Instance->SR & SAI_xSR_FLVL) != SAI_FIFOSTATUS_EMPTY)
ganlikun 0:13413ea9a877 761 {
ganlikun 0:13413ea9a877 762 if((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
ganlikun 0:13413ea9a877 763 {
ganlikun 0:13413ea9a877 764 (*hsai->pBuffPtr++) = hsai->Instance->DR;
ganlikun 0:13413ea9a877 765 }
ganlikun 0:13413ea9a877 766 else if(hsai->Init.DataSize <= SAI_DATASIZE_16)
ganlikun 0:13413ea9a877 767 {
ganlikun 0:13413ea9a877 768 *((uint16_t*)hsai->pBuffPtr) = hsai->Instance->DR;
ganlikun 0:13413ea9a877 769 hsai->pBuffPtr+= 2U;
ganlikun 0:13413ea9a877 770 }
ganlikun 0:13413ea9a877 771 else
ganlikun 0:13413ea9a877 772 {
ganlikun 0:13413ea9a877 773 *((uint32_t*)hsai->pBuffPtr) = hsai->Instance->DR;
ganlikun 0:13413ea9a877 774 hsai->pBuffPtr+= 4U;
ganlikun 0:13413ea9a877 775 }
ganlikun 0:13413ea9a877 776 hsai->XferCount--;
ganlikun 0:13413ea9a877 777 }
ganlikun 0:13413ea9a877 778 else
ganlikun 0:13413ea9a877 779 {
ganlikun 0:13413ea9a877 780 /* Check for the Timeout */
ganlikun 0:13413ea9a877 781 if((Timeout != HAL_MAX_DELAY) && ((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)))
ganlikun 0:13413ea9a877 782 {
ganlikun 0:13413ea9a877 783 /* Update error code */
ganlikun 0:13413ea9a877 784 hsai->ErrorCode |= HAL_SAI_ERROR_TIMEOUT;
ganlikun 0:13413ea9a877 785
ganlikun 0:13413ea9a877 786 /* Clear all the flags */
ganlikun 0:13413ea9a877 787 hsai->Instance->CLRFR = 0xFFFFFFFFU;
ganlikun 0:13413ea9a877 788
ganlikun 0:13413ea9a877 789 /* Disable SAI peripheral */
ganlikun 0:13413ea9a877 790 SAI_Disable(hsai);
ganlikun 0:13413ea9a877 791
ganlikun 0:13413ea9a877 792 /* Flush the fifo */
ganlikun 0:13413ea9a877 793 SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH);
ganlikun 0:13413ea9a877 794
ganlikun 0:13413ea9a877 795 /* Change the SAI state */
ganlikun 0:13413ea9a877 796 hsai->State = HAL_SAI_STATE_READY;
ganlikun 0:13413ea9a877 797
ganlikun 0:13413ea9a877 798 /* Process Unlocked */
ganlikun 0:13413ea9a877 799 __HAL_UNLOCK(hsai);
ganlikun 0:13413ea9a877 800
ganlikun 0:13413ea9a877 801 return HAL_ERROR;
ganlikun 0:13413ea9a877 802 }
ganlikun 0:13413ea9a877 803 }
ganlikun 0:13413ea9a877 804 }
ganlikun 0:13413ea9a877 805
ganlikun 0:13413ea9a877 806 hsai->State = HAL_SAI_STATE_READY;
ganlikun 0:13413ea9a877 807
ganlikun 0:13413ea9a877 808 /* Process Unlocked */
ganlikun 0:13413ea9a877 809 __HAL_UNLOCK(hsai);
ganlikun 0:13413ea9a877 810
ganlikun 0:13413ea9a877 811 return HAL_OK;
ganlikun 0:13413ea9a877 812 }
ganlikun 0:13413ea9a877 813 else
ganlikun 0:13413ea9a877 814 {
ganlikun 0:13413ea9a877 815 return HAL_BUSY;
ganlikun 0:13413ea9a877 816 }
ganlikun 0:13413ea9a877 817 }
ganlikun 0:13413ea9a877 818
ganlikun 0:13413ea9a877 819 /**
ganlikun 0:13413ea9a877 820 * @brief Transmit an amount of data in non-blocking mode with Interrupt.
ganlikun 0:13413ea9a877 821 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 822 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 823 * @param pData: Pointer to data buffer
ganlikun 0:13413ea9a877 824 * @param Size: Amount of data to be sent
ganlikun 0:13413ea9a877 825 * @retval HAL status
ganlikun 0:13413ea9a877 826 */
ganlikun 0:13413ea9a877 827 HAL_StatusTypeDef HAL_SAI_Transmit_IT(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
ganlikun 0:13413ea9a877 828 {
ganlikun 0:13413ea9a877 829 if((pData == NULL) || (Size == 0))
ganlikun 0:13413ea9a877 830 {
ganlikun 0:13413ea9a877 831 return HAL_ERROR;
ganlikun 0:13413ea9a877 832 }
ganlikun 0:13413ea9a877 833
ganlikun 0:13413ea9a877 834 if(hsai->State == HAL_SAI_STATE_READY)
ganlikun 0:13413ea9a877 835 {
ganlikun 0:13413ea9a877 836 /* Process Locked */
ganlikun 0:13413ea9a877 837 __HAL_LOCK(hsai);
ganlikun 0:13413ea9a877 838
ganlikun 0:13413ea9a877 839 hsai->pBuffPtr = pData;
ganlikun 0:13413ea9a877 840 hsai->XferSize = Size;
ganlikun 0:13413ea9a877 841 hsai->XferCount = Size;
ganlikun 0:13413ea9a877 842 hsai->ErrorCode = HAL_SAI_ERROR_NONE;
ganlikun 0:13413ea9a877 843 hsai->State = HAL_SAI_STATE_BUSY_TX;
ganlikun 0:13413ea9a877 844
ganlikun 0:13413ea9a877 845 if((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
ganlikun 0:13413ea9a877 846 {
ganlikun 0:13413ea9a877 847 hsai->InterruptServiceRoutine = SAI_Transmit_IT8Bit;
ganlikun 0:13413ea9a877 848 }
ganlikun 0:13413ea9a877 849 else if(hsai->Init.DataSize <= SAI_DATASIZE_16)
ganlikun 0:13413ea9a877 850 {
ganlikun 0:13413ea9a877 851 hsai->InterruptServiceRoutine = SAI_Transmit_IT16Bit;
ganlikun 0:13413ea9a877 852 }
ganlikun 0:13413ea9a877 853 else
ganlikun 0:13413ea9a877 854 {
ganlikun 0:13413ea9a877 855 hsai->InterruptServiceRoutine = SAI_Transmit_IT32Bit;
ganlikun 0:13413ea9a877 856 }
ganlikun 0:13413ea9a877 857
ganlikun 0:13413ea9a877 858 /* Fill the fifo before starting the communication */
ganlikun 0:13413ea9a877 859 SAI_FillFifo(hsai);
ganlikun 0:13413ea9a877 860
ganlikun 0:13413ea9a877 861 /* Enable FRQ and OVRUDR interrupts */
ganlikun 0:13413ea9a877 862 __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
ganlikun 0:13413ea9a877 863
ganlikun 0:13413ea9a877 864 /* Check if the SAI is already enabled */
ganlikun 0:13413ea9a877 865 if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET)
ganlikun 0:13413ea9a877 866 {
ganlikun 0:13413ea9a877 867 /* Enable SAI peripheral */
ganlikun 0:13413ea9a877 868 __HAL_SAI_ENABLE(hsai);
ganlikun 0:13413ea9a877 869 }
ganlikun 0:13413ea9a877 870 /* Process Unlocked */
ganlikun 0:13413ea9a877 871 __HAL_UNLOCK(hsai);
ganlikun 0:13413ea9a877 872
ganlikun 0:13413ea9a877 873 return HAL_OK;
ganlikun 0:13413ea9a877 874 }
ganlikun 0:13413ea9a877 875 else
ganlikun 0:13413ea9a877 876 {
ganlikun 0:13413ea9a877 877 return HAL_BUSY;
ganlikun 0:13413ea9a877 878 }
ganlikun 0:13413ea9a877 879 }
ganlikun 0:13413ea9a877 880
ganlikun 0:13413ea9a877 881 /**
ganlikun 0:13413ea9a877 882 * @brief Receive an amount of data in non-blocking mode with Interrupt.
ganlikun 0:13413ea9a877 883 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 884 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 885 * @param pData: Pointer to data buffer
ganlikun 0:13413ea9a877 886 * @param Size: Amount of data to be received
ganlikun 0:13413ea9a877 887 * @retval HAL status
ganlikun 0:13413ea9a877 888 */
ganlikun 0:13413ea9a877 889 HAL_StatusTypeDef HAL_SAI_Receive_IT(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
ganlikun 0:13413ea9a877 890 {
ganlikun 0:13413ea9a877 891 if((pData == NULL) || (Size == 0))
ganlikun 0:13413ea9a877 892 {
ganlikun 0:13413ea9a877 893 return HAL_ERROR;
ganlikun 0:13413ea9a877 894 }
ganlikun 0:13413ea9a877 895
ganlikun 0:13413ea9a877 896 if(hsai->State == HAL_SAI_STATE_READY)
ganlikun 0:13413ea9a877 897 {
ganlikun 0:13413ea9a877 898 /* Process Locked */
ganlikun 0:13413ea9a877 899 __HAL_LOCK(hsai);
ganlikun 0:13413ea9a877 900
ganlikun 0:13413ea9a877 901 hsai->pBuffPtr = pData;
ganlikun 0:13413ea9a877 902 hsai->XferSize = Size;
ganlikun 0:13413ea9a877 903 hsai->XferCount = Size;
ganlikun 0:13413ea9a877 904 hsai->ErrorCode = HAL_SAI_ERROR_NONE;
ganlikun 0:13413ea9a877 905 hsai->State = HAL_SAI_STATE_BUSY_RX;
ganlikun 0:13413ea9a877 906
ganlikun 0:13413ea9a877 907 if((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
ganlikun 0:13413ea9a877 908 {
ganlikun 0:13413ea9a877 909 hsai->InterruptServiceRoutine = SAI_Receive_IT8Bit;
ganlikun 0:13413ea9a877 910 }
ganlikun 0:13413ea9a877 911 else if(hsai->Init.DataSize <= SAI_DATASIZE_16)
ganlikun 0:13413ea9a877 912 {
ganlikun 0:13413ea9a877 913 hsai->InterruptServiceRoutine = SAI_Receive_IT16Bit;
ganlikun 0:13413ea9a877 914 }
ganlikun 0:13413ea9a877 915 else
ganlikun 0:13413ea9a877 916 {
ganlikun 0:13413ea9a877 917 hsai->InterruptServiceRoutine = SAI_Receive_IT32Bit;
ganlikun 0:13413ea9a877 918 }
ganlikun 0:13413ea9a877 919
ganlikun 0:13413ea9a877 920 /* Enable TXE and OVRUDR interrupts */
ganlikun 0:13413ea9a877 921 __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
ganlikun 0:13413ea9a877 922
ganlikun 0:13413ea9a877 923 /* Check if the SAI is already enabled */
ganlikun 0:13413ea9a877 924 if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET)
ganlikun 0:13413ea9a877 925 {
ganlikun 0:13413ea9a877 926 /* Enable SAI peripheral */
ganlikun 0:13413ea9a877 927 __HAL_SAI_ENABLE(hsai);
ganlikun 0:13413ea9a877 928 }
ganlikun 0:13413ea9a877 929
ganlikun 0:13413ea9a877 930 /* Process Unlocked */
ganlikun 0:13413ea9a877 931 __HAL_UNLOCK(hsai);
ganlikun 0:13413ea9a877 932
ganlikun 0:13413ea9a877 933 return HAL_OK;
ganlikun 0:13413ea9a877 934 }
ganlikun 0:13413ea9a877 935 else
ganlikun 0:13413ea9a877 936 {
ganlikun 0:13413ea9a877 937 return HAL_BUSY;
ganlikun 0:13413ea9a877 938 }
ganlikun 0:13413ea9a877 939 }
ganlikun 0:13413ea9a877 940
ganlikun 0:13413ea9a877 941 /**
ganlikun 0:13413ea9a877 942 * @brief Pause the audio stream playing from the Media.
ganlikun 0:13413ea9a877 943 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 944 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 945 * @retval HAL status
ganlikun 0:13413ea9a877 946 */
ganlikun 0:13413ea9a877 947 HAL_StatusTypeDef HAL_SAI_DMAPause(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 948 {
ganlikun 0:13413ea9a877 949 /* Process Locked */
ganlikun 0:13413ea9a877 950 __HAL_LOCK(hsai);
ganlikun 0:13413ea9a877 951
ganlikun 0:13413ea9a877 952 /* Pause the audio file playing by disabling the SAI DMA requests */
ganlikun 0:13413ea9a877 953 hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
ganlikun 0:13413ea9a877 954
ganlikun 0:13413ea9a877 955 /* Process Unlocked */
ganlikun 0:13413ea9a877 956 __HAL_UNLOCK(hsai);
ganlikun 0:13413ea9a877 957
ganlikun 0:13413ea9a877 958 return HAL_OK;
ganlikun 0:13413ea9a877 959 }
ganlikun 0:13413ea9a877 960
ganlikun 0:13413ea9a877 961 /**
ganlikun 0:13413ea9a877 962 * @brief Resume the audio stream playing from the Media.
ganlikun 0:13413ea9a877 963 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 964 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 965 * @retval HAL status
ganlikun 0:13413ea9a877 966 */
ganlikun 0:13413ea9a877 967 HAL_StatusTypeDef HAL_SAI_DMAResume(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 968 {
ganlikun 0:13413ea9a877 969 /* Process Locked */
ganlikun 0:13413ea9a877 970 __HAL_LOCK(hsai);
ganlikun 0:13413ea9a877 971
ganlikun 0:13413ea9a877 972 /* Enable the SAI DMA requests */
ganlikun 0:13413ea9a877 973 hsai->Instance->CR1 |= SAI_xCR1_DMAEN;
ganlikun 0:13413ea9a877 974
ganlikun 0:13413ea9a877 975 /* If the SAI peripheral is still not enabled, enable it */
ganlikun 0:13413ea9a877 976 if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET)
ganlikun 0:13413ea9a877 977 {
ganlikun 0:13413ea9a877 978 /* Enable SAI peripheral */
ganlikun 0:13413ea9a877 979 __HAL_SAI_ENABLE(hsai);
ganlikun 0:13413ea9a877 980 }
ganlikun 0:13413ea9a877 981
ganlikun 0:13413ea9a877 982 /* Process Unlocked */
ganlikun 0:13413ea9a877 983 __HAL_UNLOCK(hsai);
ganlikun 0:13413ea9a877 984
ganlikun 0:13413ea9a877 985 return HAL_OK;
ganlikun 0:13413ea9a877 986 }
ganlikun 0:13413ea9a877 987
ganlikun 0:13413ea9a877 988 /**
ganlikun 0:13413ea9a877 989 * @brief Stop the audio stream playing from the Media.
ganlikun 0:13413ea9a877 990 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 991 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 992 * @retval HAL status
ganlikun 0:13413ea9a877 993 */
ganlikun 0:13413ea9a877 994 HAL_StatusTypeDef HAL_SAI_DMAStop(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 995 {
ganlikun 0:13413ea9a877 996 /* Process Locked */
ganlikun 0:13413ea9a877 997 __HAL_LOCK(hsai);
ganlikun 0:13413ea9a877 998
ganlikun 0:13413ea9a877 999 /* Disable the SAI DMA request */
ganlikun 0:13413ea9a877 1000 hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
ganlikun 0:13413ea9a877 1001
ganlikun 0:13413ea9a877 1002 /* Abort the SAI DMA Streams */
ganlikun 0:13413ea9a877 1003 if(hsai->hdmatx != NULL)
ganlikun 0:13413ea9a877 1004 {
ganlikun 0:13413ea9a877 1005 if(HAL_DMA_Abort(hsai->hdmatx) != HAL_OK)
ganlikun 0:13413ea9a877 1006 {
ganlikun 0:13413ea9a877 1007 return HAL_ERROR;
ganlikun 0:13413ea9a877 1008 }
ganlikun 0:13413ea9a877 1009 }
ganlikun 0:13413ea9a877 1010
ganlikun 0:13413ea9a877 1011 if(hsai->hdmarx != NULL)
ganlikun 0:13413ea9a877 1012 {
ganlikun 0:13413ea9a877 1013 if(HAL_DMA_Abort(hsai->hdmarx) != HAL_OK)
ganlikun 0:13413ea9a877 1014 {
ganlikun 0:13413ea9a877 1015 return HAL_ERROR;
ganlikun 0:13413ea9a877 1016 }
ganlikun 0:13413ea9a877 1017 }
ganlikun 0:13413ea9a877 1018
ganlikun 0:13413ea9a877 1019 /* Disable SAI peripheral */
ganlikun 0:13413ea9a877 1020 SAI_Disable(hsai);
ganlikun 0:13413ea9a877 1021
ganlikun 0:13413ea9a877 1022 hsai->State = HAL_SAI_STATE_READY;
ganlikun 0:13413ea9a877 1023
ganlikun 0:13413ea9a877 1024 /* Process Unlocked */
ganlikun 0:13413ea9a877 1025 __HAL_UNLOCK(hsai);
ganlikun 0:13413ea9a877 1026
ganlikun 0:13413ea9a877 1027 return HAL_OK;
ganlikun 0:13413ea9a877 1028 }
ganlikun 0:13413ea9a877 1029
ganlikun 0:13413ea9a877 1030 /**
ganlikun 0:13413ea9a877 1031 * @brief Abort the current transfer and disable the SAI.
ganlikun 0:13413ea9a877 1032 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1033 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1034 * @retval HAL status
ganlikun 0:13413ea9a877 1035 */
ganlikun 0:13413ea9a877 1036 HAL_StatusTypeDef HAL_SAI_Abort(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 1037 {
ganlikun 0:13413ea9a877 1038 /* Process Locked */
ganlikun 0:13413ea9a877 1039 __HAL_LOCK(hsai);
ganlikun 0:13413ea9a877 1040
ganlikun 0:13413ea9a877 1041 /* Check SAI DMA is enabled or not */
ganlikun 0:13413ea9a877 1042 if((hsai->Instance->CR1 & SAI_xCR1_DMAEN) == SAI_xCR1_DMAEN)
ganlikun 0:13413ea9a877 1043 {
ganlikun 0:13413ea9a877 1044 /* Disable the SAI DMA request */
ganlikun 0:13413ea9a877 1045 hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
ganlikun 0:13413ea9a877 1046
ganlikun 0:13413ea9a877 1047 /* Abort the SAI DMA Streams */
ganlikun 0:13413ea9a877 1048 if(hsai->hdmatx != NULL)
ganlikun 0:13413ea9a877 1049 {
ganlikun 0:13413ea9a877 1050 if(HAL_DMA_Abort(hsai->hdmatx) != HAL_OK)
ganlikun 0:13413ea9a877 1051 {
ganlikun 0:13413ea9a877 1052 return HAL_ERROR;
ganlikun 0:13413ea9a877 1053 }
ganlikun 0:13413ea9a877 1054 }
ganlikun 0:13413ea9a877 1055
ganlikun 0:13413ea9a877 1056 if(hsai->hdmarx != NULL)
ganlikun 0:13413ea9a877 1057 {
ganlikun 0:13413ea9a877 1058 if(HAL_DMA_Abort(hsai->hdmarx) != HAL_OK)
ganlikun 0:13413ea9a877 1059 {
ganlikun 0:13413ea9a877 1060 return HAL_ERROR;
ganlikun 0:13413ea9a877 1061 }
ganlikun 0:13413ea9a877 1062 }
ganlikun 0:13413ea9a877 1063 }
ganlikun 0:13413ea9a877 1064
ganlikun 0:13413ea9a877 1065 /* Disabled All interrupt and clear all the flag */
ganlikun 0:13413ea9a877 1066 hsai->Instance->IMR = 0U;
ganlikun 0:13413ea9a877 1067 hsai->Instance->CLRFR = 0xFFFFFFFFU;
ganlikun 0:13413ea9a877 1068
ganlikun 0:13413ea9a877 1069 /* Disable SAI peripheral */
ganlikun 0:13413ea9a877 1070 SAI_Disable(hsai);
ganlikun 0:13413ea9a877 1071
ganlikun 0:13413ea9a877 1072 /* Flush the fifo */
ganlikun 0:13413ea9a877 1073 SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH);
ganlikun 0:13413ea9a877 1074
ganlikun 0:13413ea9a877 1075 hsai->State = HAL_SAI_STATE_READY;
ganlikun 0:13413ea9a877 1076
ganlikun 0:13413ea9a877 1077 /* Process Unlocked */
ganlikun 0:13413ea9a877 1078 __HAL_UNLOCK(hsai);
ganlikun 0:13413ea9a877 1079
ganlikun 0:13413ea9a877 1080 return HAL_OK;
ganlikun 0:13413ea9a877 1081 }
ganlikun 0:13413ea9a877 1082
ganlikun 0:13413ea9a877 1083 /**
ganlikun 0:13413ea9a877 1084 * @brief Transmit an amount of data in non-blocking mode with DMA.
ganlikun 0:13413ea9a877 1085 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1086 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1087 * @param pData: Pointer to data buffer
ganlikun 0:13413ea9a877 1088 * @param Size: Amount of data to be sent
ganlikun 0:13413ea9a877 1089 * @retval HAL status
ganlikun 0:13413ea9a877 1090 */
ganlikun 0:13413ea9a877 1091 HAL_StatusTypeDef HAL_SAI_Transmit_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
ganlikun 0:13413ea9a877 1092 {
ganlikun 0:13413ea9a877 1093 if((pData == NULL) || (Size == 0))
ganlikun 0:13413ea9a877 1094 {
ganlikun 0:13413ea9a877 1095 return HAL_ERROR;
ganlikun 0:13413ea9a877 1096 }
ganlikun 0:13413ea9a877 1097
ganlikun 0:13413ea9a877 1098 if(hsai->State == HAL_SAI_STATE_READY)
ganlikun 0:13413ea9a877 1099 {
ganlikun 0:13413ea9a877 1100 /* Process Locked */
ganlikun 0:13413ea9a877 1101 __HAL_LOCK(hsai);
ganlikun 0:13413ea9a877 1102
ganlikun 0:13413ea9a877 1103 hsai->pBuffPtr = pData;
ganlikun 0:13413ea9a877 1104 hsai->XferSize = Size;
ganlikun 0:13413ea9a877 1105 hsai->XferCount = Size;
ganlikun 0:13413ea9a877 1106 hsai->ErrorCode = HAL_SAI_ERROR_NONE;
ganlikun 0:13413ea9a877 1107 hsai->State = HAL_SAI_STATE_BUSY_TX;
ganlikun 0:13413ea9a877 1108
ganlikun 0:13413ea9a877 1109 /* Set the SAI Tx DMA Half transfer complete callback */
ganlikun 0:13413ea9a877 1110 hsai->hdmatx->XferHalfCpltCallback = SAI_DMATxHalfCplt;
ganlikun 0:13413ea9a877 1111
ganlikun 0:13413ea9a877 1112 /* Set the SAI TxDMA transfer complete callback */
ganlikun 0:13413ea9a877 1113 hsai->hdmatx->XferCpltCallback = SAI_DMATxCplt;
ganlikun 0:13413ea9a877 1114
ganlikun 0:13413ea9a877 1115 /* Set the DMA error callback */
ganlikun 0:13413ea9a877 1116 hsai->hdmatx->XferErrorCallback = SAI_DMAError;
ganlikun 0:13413ea9a877 1117
ganlikun 0:13413ea9a877 1118 /* Set the DMA Tx abort callback */
ganlikun 0:13413ea9a877 1119 hsai->hdmatx->XferAbortCallback = NULL;
ganlikun 0:13413ea9a877 1120
ganlikun 0:13413ea9a877 1121 /* Enable the Tx DMA Stream */
ganlikun 0:13413ea9a877 1122 if(HAL_DMA_Start_IT(hsai->hdmatx, (uint32_t)hsai->pBuffPtr, (uint32_t)&hsai->Instance->DR, hsai->XferSize) != HAL_OK)
ganlikun 0:13413ea9a877 1123 {
ganlikun 0:13413ea9a877 1124 __HAL_UNLOCK(hsai);
ganlikun 0:13413ea9a877 1125 return HAL_ERROR;
ganlikun 0:13413ea9a877 1126 }
ganlikun 0:13413ea9a877 1127
ganlikun 0:13413ea9a877 1128 /* Check if the SAI is already enabled */
ganlikun 0:13413ea9a877 1129 if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET)
ganlikun 0:13413ea9a877 1130 {
ganlikun 0:13413ea9a877 1131 /* Enable SAI peripheral */
ganlikun 0:13413ea9a877 1132 __HAL_SAI_ENABLE(hsai);
ganlikun 0:13413ea9a877 1133 }
ganlikun 0:13413ea9a877 1134
ganlikun 0:13413ea9a877 1135 /* Enable the interrupts for error handling */
ganlikun 0:13413ea9a877 1136 __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA));
ganlikun 0:13413ea9a877 1137
ganlikun 0:13413ea9a877 1138 /* Enable SAI Tx DMA Request */
ganlikun 0:13413ea9a877 1139 hsai->Instance->CR1 |= SAI_xCR1_DMAEN;
ganlikun 0:13413ea9a877 1140
ganlikun 0:13413ea9a877 1141 /* Process Unlocked */
ganlikun 0:13413ea9a877 1142 __HAL_UNLOCK(hsai);
ganlikun 0:13413ea9a877 1143
ganlikun 0:13413ea9a877 1144 return HAL_OK;
ganlikun 0:13413ea9a877 1145 }
ganlikun 0:13413ea9a877 1146 else
ganlikun 0:13413ea9a877 1147 {
ganlikun 0:13413ea9a877 1148 return HAL_BUSY;
ganlikun 0:13413ea9a877 1149 }
ganlikun 0:13413ea9a877 1150 }
ganlikun 0:13413ea9a877 1151
ganlikun 0:13413ea9a877 1152 /**
ganlikun 0:13413ea9a877 1153 * @brief Receive an amount of data in non-blocking mode with DMA.
ganlikun 0:13413ea9a877 1154 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1155 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1156 * @param pData: Pointer to data buffer
ganlikun 0:13413ea9a877 1157 * @param Size: Amount of data to be received
ganlikun 0:13413ea9a877 1158 * @retval HAL status
ganlikun 0:13413ea9a877 1159 */
ganlikun 0:13413ea9a877 1160 HAL_StatusTypeDef HAL_SAI_Receive_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
ganlikun 0:13413ea9a877 1161 {
ganlikun 0:13413ea9a877 1162 if((pData == NULL) || (Size == 0))
ganlikun 0:13413ea9a877 1163 {
ganlikun 0:13413ea9a877 1164 return HAL_ERROR;
ganlikun 0:13413ea9a877 1165 }
ganlikun 0:13413ea9a877 1166
ganlikun 0:13413ea9a877 1167 if(hsai->State == HAL_SAI_STATE_READY)
ganlikun 0:13413ea9a877 1168 {
ganlikun 0:13413ea9a877 1169 /* Process Locked */
ganlikun 0:13413ea9a877 1170 __HAL_LOCK(hsai);
ganlikun 0:13413ea9a877 1171
ganlikun 0:13413ea9a877 1172 hsai->pBuffPtr = pData;
ganlikun 0:13413ea9a877 1173 hsai->XferSize = Size;
ganlikun 0:13413ea9a877 1174 hsai->XferCount = Size;
ganlikun 0:13413ea9a877 1175 hsai->ErrorCode = HAL_SAI_ERROR_NONE;
ganlikun 0:13413ea9a877 1176 hsai->State = HAL_SAI_STATE_BUSY_RX;
ganlikun 0:13413ea9a877 1177
ganlikun 0:13413ea9a877 1178 /* Set the SAI Rx DMA Half transfer complete callback */
ganlikun 0:13413ea9a877 1179 hsai->hdmarx->XferHalfCpltCallback = SAI_DMARxHalfCplt;
ganlikun 0:13413ea9a877 1180
ganlikun 0:13413ea9a877 1181 /* Set the SAI Rx DMA transfer complete callback */
ganlikun 0:13413ea9a877 1182 hsai->hdmarx->XferCpltCallback = SAI_DMARxCplt;
ganlikun 0:13413ea9a877 1183
ganlikun 0:13413ea9a877 1184 /* Set the DMA error callback */
ganlikun 0:13413ea9a877 1185 hsai->hdmarx->XferErrorCallback = SAI_DMAError;
ganlikun 0:13413ea9a877 1186
ganlikun 0:13413ea9a877 1187 /* Set the DMA Rx abort callback */
ganlikun 0:13413ea9a877 1188 hsai->hdmarx->XferAbortCallback = NULL;
ganlikun 0:13413ea9a877 1189
ganlikun 0:13413ea9a877 1190 /* Enable the Rx DMA Stream */
ganlikun 0:13413ea9a877 1191 if(HAL_DMA_Start_IT(hsai->hdmarx, (uint32_t)&hsai->Instance->DR, (uint32_t)hsai->pBuffPtr, hsai->XferSize) != HAL_OK)
ganlikun 0:13413ea9a877 1192 {
ganlikun 0:13413ea9a877 1193 __HAL_UNLOCK(hsai);
ganlikun 0:13413ea9a877 1194 return HAL_ERROR;
ganlikun 0:13413ea9a877 1195 }
ganlikun 0:13413ea9a877 1196
ganlikun 0:13413ea9a877 1197 /* Check if the SAI is already enabled */
ganlikun 0:13413ea9a877 1198 if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET)
ganlikun 0:13413ea9a877 1199 {
ganlikun 0:13413ea9a877 1200 /* Enable SAI peripheral */
ganlikun 0:13413ea9a877 1201 __HAL_SAI_ENABLE(hsai);
ganlikun 0:13413ea9a877 1202 }
ganlikun 0:13413ea9a877 1203
ganlikun 0:13413ea9a877 1204 /* Enable the interrupts for error handling */
ganlikun 0:13413ea9a877 1205 __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA));
ganlikun 0:13413ea9a877 1206
ganlikun 0:13413ea9a877 1207 /* Enable SAI Rx DMA Request */
ganlikun 0:13413ea9a877 1208 hsai->Instance->CR1 |= SAI_xCR1_DMAEN;
ganlikun 0:13413ea9a877 1209
ganlikun 0:13413ea9a877 1210 /* Process Unlocked */
ganlikun 0:13413ea9a877 1211 __HAL_UNLOCK(hsai);
ganlikun 0:13413ea9a877 1212
ganlikun 0:13413ea9a877 1213 return HAL_OK;
ganlikun 0:13413ea9a877 1214 }
ganlikun 0:13413ea9a877 1215 else
ganlikun 0:13413ea9a877 1216 {
ganlikun 0:13413ea9a877 1217 return HAL_BUSY;
ganlikun 0:13413ea9a877 1218 }
ganlikun 0:13413ea9a877 1219 }
ganlikun 0:13413ea9a877 1220
ganlikun 0:13413ea9a877 1221 /**
ganlikun 0:13413ea9a877 1222 * @brief Enable the Tx mute mode.
ganlikun 0:13413ea9a877 1223 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1224 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1225 * @param val: value sent during the mute @ref SAI_Block_Mute_Value
ganlikun 0:13413ea9a877 1226 * @retval HAL status
ganlikun 0:13413ea9a877 1227 */
ganlikun 0:13413ea9a877 1228 HAL_StatusTypeDef HAL_SAI_EnableTxMuteMode(SAI_HandleTypeDef *hsai, uint16_t val)
ganlikun 0:13413ea9a877 1229 {
ganlikun 0:13413ea9a877 1230 assert_param(IS_SAI_BLOCK_MUTE_VALUE(val));
ganlikun 0:13413ea9a877 1231
ganlikun 0:13413ea9a877 1232 if(hsai->State != HAL_SAI_STATE_RESET)
ganlikun 0:13413ea9a877 1233 {
ganlikun 0:13413ea9a877 1234 CLEAR_BIT(hsai->Instance->CR2, SAI_xCR2_MUTEVAL | SAI_xCR2_MUTE);
ganlikun 0:13413ea9a877 1235 SET_BIT(hsai->Instance->CR2, SAI_xCR2_MUTE | val);
ganlikun 0:13413ea9a877 1236 return HAL_OK;
ganlikun 0:13413ea9a877 1237 }
ganlikun 0:13413ea9a877 1238 return HAL_ERROR;
ganlikun 0:13413ea9a877 1239 }
ganlikun 0:13413ea9a877 1240
ganlikun 0:13413ea9a877 1241 /**
ganlikun 0:13413ea9a877 1242 * @brief Disable the Tx mute mode.
ganlikun 0:13413ea9a877 1243 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1244 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1245 * @retval HAL status
ganlikun 0:13413ea9a877 1246 */
ganlikun 0:13413ea9a877 1247 HAL_StatusTypeDef HAL_SAI_DisableTxMuteMode(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 1248 {
ganlikun 0:13413ea9a877 1249 if(hsai->State != HAL_SAI_STATE_RESET)
ganlikun 0:13413ea9a877 1250 {
ganlikun 0:13413ea9a877 1251 CLEAR_BIT(hsai->Instance->CR2, SAI_xCR2_MUTEVAL | SAI_xCR2_MUTE);
ganlikun 0:13413ea9a877 1252 return HAL_OK;
ganlikun 0:13413ea9a877 1253 }
ganlikun 0:13413ea9a877 1254 return HAL_ERROR;
ganlikun 0:13413ea9a877 1255 }
ganlikun 0:13413ea9a877 1256
ganlikun 0:13413ea9a877 1257 /**
ganlikun 0:13413ea9a877 1258 * @brief Enable the Rx mute detection.
ganlikun 0:13413ea9a877 1259 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1260 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1261 * @param callback: function called when the mute is detected.
ganlikun 0:13413ea9a877 1262 * @param counter: number a data before mute detection max 63.
ganlikun 0:13413ea9a877 1263 * @retval HAL status
ganlikun 0:13413ea9a877 1264 */
ganlikun 0:13413ea9a877 1265 HAL_StatusTypeDef HAL_SAI_EnableRxMuteMode(SAI_HandleTypeDef *hsai, SAIcallback callback, uint16_t counter)
ganlikun 0:13413ea9a877 1266 {
ganlikun 0:13413ea9a877 1267 assert_param(IS_SAI_BLOCK_MUTE_COUNTER(counter));
ganlikun 0:13413ea9a877 1268
ganlikun 0:13413ea9a877 1269 if(hsai->State != HAL_SAI_STATE_RESET)
ganlikun 0:13413ea9a877 1270 {
ganlikun 0:13413ea9a877 1271 /* set the mute counter */
ganlikun 0:13413ea9a877 1272 CLEAR_BIT(hsai->Instance->CR2, SAI_xCR2_MUTECNT);
ganlikun 0:13413ea9a877 1273 SET_BIT(hsai->Instance->CR2, (uint32_t)((uint32_t)counter << SAI_xCR2_MUTECNT_OFFSET));
ganlikun 0:13413ea9a877 1274 hsai->mutecallback = callback;
ganlikun 0:13413ea9a877 1275 /* enable the IT interrupt */
ganlikun 0:13413ea9a877 1276 __HAL_SAI_ENABLE_IT(hsai, SAI_IT_MUTEDET);
ganlikun 0:13413ea9a877 1277 return HAL_OK;
ganlikun 0:13413ea9a877 1278 }
ganlikun 0:13413ea9a877 1279 return HAL_ERROR;
ganlikun 0:13413ea9a877 1280 }
ganlikun 0:13413ea9a877 1281
ganlikun 0:13413ea9a877 1282 /**
ganlikun 0:13413ea9a877 1283 * @brief Disable the Rx mute detection.
ganlikun 0:13413ea9a877 1284 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1285 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1286 * @retval HAL status
ganlikun 0:13413ea9a877 1287 */
ganlikun 0:13413ea9a877 1288 HAL_StatusTypeDef HAL_SAI_DisableRxMuteMode(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 1289 {
ganlikun 0:13413ea9a877 1290 if(hsai->State != HAL_SAI_STATE_RESET)
ganlikun 0:13413ea9a877 1291 {
ganlikun 0:13413ea9a877 1292 /* set the mutecallback to NULL */
ganlikun 0:13413ea9a877 1293 hsai->mutecallback = (SAIcallback)NULL;
ganlikun 0:13413ea9a877 1294 /* enable the IT interrupt */
ganlikun 0:13413ea9a877 1295 __HAL_SAI_DISABLE_IT(hsai, SAI_IT_MUTEDET);
ganlikun 0:13413ea9a877 1296 return HAL_OK;
ganlikun 0:13413ea9a877 1297 }
ganlikun 0:13413ea9a877 1298 return HAL_ERROR;
ganlikun 0:13413ea9a877 1299 }
ganlikun 0:13413ea9a877 1300
ganlikun 0:13413ea9a877 1301 /**
ganlikun 0:13413ea9a877 1302 * @brief Handle SAI interrupt request.
ganlikun 0:13413ea9a877 1303 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1304 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1305 * @retval None
ganlikun 0:13413ea9a877 1306 */
ganlikun 0:13413ea9a877 1307 void HAL_SAI_IRQHandler(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 1308 {
ganlikun 0:13413ea9a877 1309 if(hsai->State != HAL_SAI_STATE_RESET)
ganlikun 0:13413ea9a877 1310 {
ganlikun 0:13413ea9a877 1311 uint32_t itflags = hsai->Instance->SR;
ganlikun 0:13413ea9a877 1312 uint32_t itsources = hsai->Instance->IMR;
ganlikun 0:13413ea9a877 1313 uint32_t cr1config = hsai->Instance->CR1;
ganlikun 0:13413ea9a877 1314 uint32_t tmperror;
ganlikun 0:13413ea9a877 1315
ganlikun 0:13413ea9a877 1316 /* SAI Fifo request interrupt occured ------------------------------------*/
ganlikun 0:13413ea9a877 1317 if(((itflags & SAI_xSR_FREQ) == SAI_xSR_FREQ) && ((itsources & SAI_IT_FREQ) == SAI_IT_FREQ))
ganlikun 0:13413ea9a877 1318 {
ganlikun 0:13413ea9a877 1319 hsai->InterruptServiceRoutine(hsai);
ganlikun 0:13413ea9a877 1320 }
ganlikun 0:13413ea9a877 1321 /* SAI Overrun error interrupt occurred ----------------------------------*/
ganlikun 0:13413ea9a877 1322 else if(((itflags & SAI_FLAG_OVRUDR) == SAI_FLAG_OVRUDR) && ((itsources & SAI_IT_OVRUDR) == SAI_IT_OVRUDR))
ganlikun 0:13413ea9a877 1323 {
ganlikun 0:13413ea9a877 1324 /* Clear the SAI Overrun flag */
ganlikun 0:13413ea9a877 1325 __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR);
ganlikun 0:13413ea9a877 1326
ganlikun 0:13413ea9a877 1327 /* Get the SAI error code */
ganlikun 0:13413ea9a877 1328 tmperror = ((hsai->State == HAL_SAI_STATE_BUSY_RX) ? HAL_SAI_ERROR_OVR : HAL_SAI_ERROR_UDR);
ganlikun 0:13413ea9a877 1329
ganlikun 0:13413ea9a877 1330 /* Change the SAI error code */
ganlikun 0:13413ea9a877 1331 hsai->ErrorCode |= tmperror;
ganlikun 0:13413ea9a877 1332
ganlikun 0:13413ea9a877 1333 /* the transfer is not stopped, we will forward the information to the user and we let the user decide what needs to be done */
ganlikun 0:13413ea9a877 1334 HAL_SAI_ErrorCallback(hsai);
ganlikun 0:13413ea9a877 1335 }
ganlikun 0:13413ea9a877 1336 /* SAI mutedet interrupt occurred ----------------------------------*/
ganlikun 0:13413ea9a877 1337 else if(((itflags & SAI_FLAG_MUTEDET) == SAI_FLAG_MUTEDET) && ((itsources & SAI_IT_MUTEDET) == SAI_IT_MUTEDET))
ganlikun 0:13413ea9a877 1338 {
ganlikun 0:13413ea9a877 1339 /* Clear the SAI mutedet flag */
ganlikun 0:13413ea9a877 1340 __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_MUTEDET);
ganlikun 0:13413ea9a877 1341
ganlikun 0:13413ea9a877 1342 /* call the call back function */
ganlikun 0:13413ea9a877 1343 if(hsai->mutecallback != (SAIcallback)NULL)
ganlikun 0:13413ea9a877 1344 {
ganlikun 0:13413ea9a877 1345 /* inform the user that an RX mute event has been detected */
ganlikun 0:13413ea9a877 1346 hsai->mutecallback();
ganlikun 0:13413ea9a877 1347 }
ganlikun 0:13413ea9a877 1348 }
ganlikun 0:13413ea9a877 1349 /* SAI AFSDET interrupt occurred ----------------------------------*/
ganlikun 0:13413ea9a877 1350 else if(((itflags & SAI_FLAG_AFSDET) == SAI_FLAG_AFSDET) && ((itsources & SAI_IT_AFSDET) == SAI_IT_AFSDET))
ganlikun 0:13413ea9a877 1351 {
ganlikun 0:13413ea9a877 1352 /* Change the SAI error code */
ganlikun 0:13413ea9a877 1353 hsai->ErrorCode |= HAL_SAI_ERROR_AFSDET;
ganlikun 0:13413ea9a877 1354
ganlikun 0:13413ea9a877 1355 /* Check SAI DMA is enabled or not */
ganlikun 0:13413ea9a877 1356 if((cr1config & SAI_xCR1_DMAEN) == SAI_xCR1_DMAEN)
ganlikun 0:13413ea9a877 1357 {
ganlikun 0:13413ea9a877 1358 /* Abort the SAI DMA Streams */
ganlikun 0:13413ea9a877 1359 if(hsai->hdmatx != NULL)
ganlikun 0:13413ea9a877 1360 {
ganlikun 0:13413ea9a877 1361 /* Set the DMA Tx abort callback */
ganlikun 0:13413ea9a877 1362 hsai->hdmatx->XferAbortCallback = SAI_DMAAbort;
ganlikun 0:13413ea9a877 1363
ganlikun 0:13413ea9a877 1364 /* Abort DMA in IT mode */
ganlikun 0:13413ea9a877 1365 HAL_DMA_Abort_IT(hsai->hdmatx);
ganlikun 0:13413ea9a877 1366 }
ganlikun 0:13413ea9a877 1367 else if(hsai->hdmarx != NULL)
ganlikun 0:13413ea9a877 1368 {
ganlikun 0:13413ea9a877 1369 /* Set the DMA Rx abort callback */
ganlikun 0:13413ea9a877 1370 hsai->hdmarx->XferAbortCallback = SAI_DMAAbort;
ganlikun 0:13413ea9a877 1371
ganlikun 0:13413ea9a877 1372 /* Abort DMA in IT mode */
ganlikun 0:13413ea9a877 1373 HAL_DMA_Abort_IT(hsai->hdmarx);
ganlikun 0:13413ea9a877 1374 }
ganlikun 0:13413ea9a877 1375 }
ganlikun 0:13413ea9a877 1376 else
ganlikun 0:13413ea9a877 1377 {
ganlikun 0:13413ea9a877 1378 /* Abort SAI */
ganlikun 0:13413ea9a877 1379 HAL_SAI_Abort(hsai);
ganlikun 0:13413ea9a877 1380
ganlikun 0:13413ea9a877 1381 /* Set error callback */
ganlikun 0:13413ea9a877 1382 HAL_SAI_ErrorCallback(hsai);
ganlikun 0:13413ea9a877 1383 }
ganlikun 0:13413ea9a877 1384 }
ganlikun 0:13413ea9a877 1385 /* SAI LFSDET interrupt occurred ----------------------------------*/
ganlikun 0:13413ea9a877 1386 else if(((itflags & SAI_FLAG_LFSDET) == SAI_FLAG_LFSDET) && ((itsources & SAI_IT_LFSDET) == SAI_IT_LFSDET))
ganlikun 0:13413ea9a877 1387 {
ganlikun 0:13413ea9a877 1388 /* Change the SAI error code */
ganlikun 0:13413ea9a877 1389 hsai->ErrorCode |= HAL_SAI_ERROR_LFSDET;
ganlikun 0:13413ea9a877 1390
ganlikun 0:13413ea9a877 1391 /* Check SAI DMA is enabled or not */
ganlikun 0:13413ea9a877 1392 if((cr1config & SAI_xCR1_DMAEN) == SAI_xCR1_DMAEN)
ganlikun 0:13413ea9a877 1393 {
ganlikun 0:13413ea9a877 1394 /* Abort the SAI DMA Streams */
ganlikun 0:13413ea9a877 1395 if(hsai->hdmatx != NULL)
ganlikun 0:13413ea9a877 1396 {
ganlikun 0:13413ea9a877 1397 /* Set the DMA Tx abort callback */
ganlikun 0:13413ea9a877 1398 hsai->hdmatx->XferAbortCallback = SAI_DMAAbort;
ganlikun 0:13413ea9a877 1399
ganlikun 0:13413ea9a877 1400 /* Abort DMA in IT mode */
ganlikun 0:13413ea9a877 1401 HAL_DMA_Abort_IT(hsai->hdmatx);
ganlikun 0:13413ea9a877 1402 }
ganlikun 0:13413ea9a877 1403 else if(hsai->hdmarx != NULL)
ganlikun 0:13413ea9a877 1404 {
ganlikun 0:13413ea9a877 1405 /* Set the DMA Rx abort callback */
ganlikun 0:13413ea9a877 1406 hsai->hdmarx->XferAbortCallback = SAI_DMAAbort;
ganlikun 0:13413ea9a877 1407
ganlikun 0:13413ea9a877 1408 /* Abort DMA in IT mode */
ganlikun 0:13413ea9a877 1409 HAL_DMA_Abort_IT(hsai->hdmarx);
ganlikun 0:13413ea9a877 1410 }
ganlikun 0:13413ea9a877 1411 }
ganlikun 0:13413ea9a877 1412 else
ganlikun 0:13413ea9a877 1413 {
ganlikun 0:13413ea9a877 1414 /* Abort SAI */
ganlikun 0:13413ea9a877 1415 HAL_SAI_Abort(hsai);
ganlikun 0:13413ea9a877 1416
ganlikun 0:13413ea9a877 1417 /* Set error callback */
ganlikun 0:13413ea9a877 1418 HAL_SAI_ErrorCallback(hsai);
ganlikun 0:13413ea9a877 1419 }
ganlikun 0:13413ea9a877 1420 }
ganlikun 0:13413ea9a877 1421 /* SAI WCKCFG interrupt occurred ----------------------------------*/
ganlikun 0:13413ea9a877 1422 else if(((itflags & SAI_FLAG_WCKCFG) == SAI_FLAG_WCKCFG) && ((itsources & SAI_IT_WCKCFG) == SAI_IT_WCKCFG))
ganlikun 0:13413ea9a877 1423 {
ganlikun 0:13413ea9a877 1424 /* Change the SAI error code */
ganlikun 0:13413ea9a877 1425 hsai->ErrorCode |= HAL_SAI_ERROR_WCKCFG;
ganlikun 0:13413ea9a877 1426
ganlikun 0:13413ea9a877 1427 /* Check SAI DMA is enabled or not */
ganlikun 0:13413ea9a877 1428 if((cr1config & SAI_xCR1_DMAEN) == SAI_xCR1_DMAEN)
ganlikun 0:13413ea9a877 1429 {
ganlikun 0:13413ea9a877 1430 /* Abort the SAI DMA Streams */
ganlikun 0:13413ea9a877 1431 if(hsai->hdmatx != NULL)
ganlikun 0:13413ea9a877 1432 {
ganlikun 0:13413ea9a877 1433 /* Set the DMA Tx abort callback */
ganlikun 0:13413ea9a877 1434 hsai->hdmatx->XferAbortCallback = SAI_DMAAbort;
ganlikun 0:13413ea9a877 1435
ganlikun 0:13413ea9a877 1436 /* Abort DMA in IT mode */
ganlikun 0:13413ea9a877 1437 HAL_DMA_Abort_IT(hsai->hdmatx);
ganlikun 0:13413ea9a877 1438 }
ganlikun 0:13413ea9a877 1439 else if(hsai->hdmarx != NULL)
ganlikun 0:13413ea9a877 1440 {
ganlikun 0:13413ea9a877 1441 /* Set the DMA Rx abort callback */
ganlikun 0:13413ea9a877 1442 hsai->hdmarx->XferAbortCallback = SAI_DMAAbort;
ganlikun 0:13413ea9a877 1443
ganlikun 0:13413ea9a877 1444 /* Abort DMA in IT mode */
ganlikun 0:13413ea9a877 1445 HAL_DMA_Abort_IT(hsai->hdmarx);
ganlikun 0:13413ea9a877 1446 }
ganlikun 0:13413ea9a877 1447 }
ganlikun 0:13413ea9a877 1448 else
ganlikun 0:13413ea9a877 1449 {
ganlikun 0:13413ea9a877 1450 /* If WCKCFG occurs, SAI audio block is automatically disabled */
ganlikun 0:13413ea9a877 1451 /* Disable all interrupts and clear all flags */
ganlikun 0:13413ea9a877 1452 hsai->Instance->IMR = 0U;
ganlikun 0:13413ea9a877 1453 hsai->Instance->CLRFR = 0xFFFFFFFFU;
ganlikun 0:13413ea9a877 1454
ganlikun 0:13413ea9a877 1455 /* Set the SAI state to ready to be able to start again the process */
ganlikun 0:13413ea9a877 1456 hsai->State = HAL_SAI_STATE_READY;
ganlikun 0:13413ea9a877 1457
ganlikun 0:13413ea9a877 1458 /* Initialize XferCount */
ganlikun 0:13413ea9a877 1459 hsai->XferCount = 0U;
ganlikun 0:13413ea9a877 1460
ganlikun 0:13413ea9a877 1461 /* SAI error Callback */
ganlikun 0:13413ea9a877 1462 HAL_SAI_ErrorCallback(hsai);
ganlikun 0:13413ea9a877 1463 }
ganlikun 0:13413ea9a877 1464 }
ganlikun 0:13413ea9a877 1465 /* SAI CNRDY interrupt occurred ----------------------------------*/
ganlikun 0:13413ea9a877 1466 else if(((itflags & SAI_FLAG_CNRDY) == SAI_FLAG_CNRDY) && ((itsources & SAI_IT_CNRDY) == SAI_IT_CNRDY))
ganlikun 0:13413ea9a877 1467 {
ganlikun 0:13413ea9a877 1468 /* Clear the SAI CNRDY flag */
ganlikun 0:13413ea9a877 1469 __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_CNRDY);
ganlikun 0:13413ea9a877 1470
ganlikun 0:13413ea9a877 1471 /* Change the SAI error code */
ganlikun 0:13413ea9a877 1472 hsai->ErrorCode |= HAL_SAI_ERROR_CNREADY;
ganlikun 0:13413ea9a877 1473
ganlikun 0:13413ea9a877 1474 /* the transfer is not stopped, we will forward the information to the user and we let the user decide what needs to be done */
ganlikun 0:13413ea9a877 1475 HAL_SAI_ErrorCallback(hsai);
ganlikun 0:13413ea9a877 1476 }
ganlikun 0:13413ea9a877 1477 else
ganlikun 0:13413ea9a877 1478 {
ganlikun 0:13413ea9a877 1479 /* Nothing to do */
ganlikun 0:13413ea9a877 1480 }
ganlikun 0:13413ea9a877 1481 }
ganlikun 0:13413ea9a877 1482 }
ganlikun 0:13413ea9a877 1483
ganlikun 0:13413ea9a877 1484 /**
ganlikun 0:13413ea9a877 1485 * @brief Tx Transfer completed callback.
ganlikun 0:13413ea9a877 1486 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1487 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1488 * @retval None
ganlikun 0:13413ea9a877 1489 */
ganlikun 0:13413ea9a877 1490 __weak void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 1491 {
ganlikun 0:13413ea9a877 1492 /* Prevent unused argument(s) compilation warning */
ganlikun 0:13413ea9a877 1493 UNUSED(hsai);
ganlikun 0:13413ea9a877 1494
ganlikun 0:13413ea9a877 1495 /* NOTE : This function should not be modified, when the callback is needed,
ganlikun 0:13413ea9a877 1496 the HAL_SAI_TxCpltCallback could be implemented in the user file
ganlikun 0:13413ea9a877 1497 */
ganlikun 0:13413ea9a877 1498 }
ganlikun 0:13413ea9a877 1499
ganlikun 0:13413ea9a877 1500 /**
ganlikun 0:13413ea9a877 1501 * @brief Tx Transfer Half completed callback.
ganlikun 0:13413ea9a877 1502 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1503 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1504 * @retval None
ganlikun 0:13413ea9a877 1505 */
ganlikun 0:13413ea9a877 1506 __weak void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 1507 {
ganlikun 0:13413ea9a877 1508 /* Prevent unused argument(s) compilation warning */
ganlikun 0:13413ea9a877 1509 UNUSED(hsai);
ganlikun 0:13413ea9a877 1510
ganlikun 0:13413ea9a877 1511 /* NOTE : This function should not be modified, when the callback is needed,
ganlikun 0:13413ea9a877 1512 the HAL_SAI_TxHalfCpltCallback could be implemented in the user file
ganlikun 0:13413ea9a877 1513 */
ganlikun 0:13413ea9a877 1514 }
ganlikun 0:13413ea9a877 1515
ganlikun 0:13413ea9a877 1516 /**
ganlikun 0:13413ea9a877 1517 * @brief Rx Transfer completed callback.
ganlikun 0:13413ea9a877 1518 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1519 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1520 * @retval None
ganlikun 0:13413ea9a877 1521 */
ganlikun 0:13413ea9a877 1522 __weak void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 1523 {
ganlikun 0:13413ea9a877 1524 /* Prevent unused argument(s) compilation warning */
ganlikun 0:13413ea9a877 1525 UNUSED(hsai);
ganlikun 0:13413ea9a877 1526
ganlikun 0:13413ea9a877 1527 /* NOTE : This function should not be modified, when the callback is needed,
ganlikun 0:13413ea9a877 1528 the HAL_SAI_RxCpltCallback could be implemented in the user file
ganlikun 0:13413ea9a877 1529 */
ganlikun 0:13413ea9a877 1530 }
ganlikun 0:13413ea9a877 1531
ganlikun 0:13413ea9a877 1532 /**
ganlikun 0:13413ea9a877 1533 * @brief Rx Transfer half completed callback.
ganlikun 0:13413ea9a877 1534 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1535 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1536 * @retval None
ganlikun 0:13413ea9a877 1537 */
ganlikun 0:13413ea9a877 1538 __weak void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 1539 {
ganlikun 0:13413ea9a877 1540 /* Prevent unused argument(s) compilation warning */
ganlikun 0:13413ea9a877 1541 UNUSED(hsai);
ganlikun 0:13413ea9a877 1542
ganlikun 0:13413ea9a877 1543 /* NOTE : This function should not be modified, when the callback is needed,
ganlikun 0:13413ea9a877 1544 the HAL_SAI_RxHalfCpltCallback could be implemented in the user file
ganlikun 0:13413ea9a877 1545 */
ganlikun 0:13413ea9a877 1546 }
ganlikun 0:13413ea9a877 1547
ganlikun 0:13413ea9a877 1548 /**
ganlikun 0:13413ea9a877 1549 * @brief SAI error callback.
ganlikun 0:13413ea9a877 1550 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1551 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1552 * @retval None
ganlikun 0:13413ea9a877 1553 */
ganlikun 0:13413ea9a877 1554 __weak void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 1555 {
ganlikun 0:13413ea9a877 1556 /* Prevent unused argument(s) compilation warning */
ganlikun 0:13413ea9a877 1557 UNUSED(hsai);
ganlikun 0:13413ea9a877 1558
ganlikun 0:13413ea9a877 1559 /* NOTE : This function should not be modified, when the callback is needed,
ganlikun 0:13413ea9a877 1560 the HAL_SAI_ErrorCallback could be implemented in the user file
ganlikun 0:13413ea9a877 1561 */
ganlikun 0:13413ea9a877 1562 }
ganlikun 0:13413ea9a877 1563
ganlikun 0:13413ea9a877 1564 /**
ganlikun 0:13413ea9a877 1565 * @}
ganlikun 0:13413ea9a877 1566 */
ganlikun 0:13413ea9a877 1567
ganlikun 0:13413ea9a877 1568
ganlikun 0:13413ea9a877 1569 /** @defgroup SAI_Exported_Functions_Group3 Peripheral State functions
ganlikun 0:13413ea9a877 1570 * @brief Peripheral State functions
ganlikun 0:13413ea9a877 1571 *
ganlikun 0:13413ea9a877 1572 @verbatim
ganlikun 0:13413ea9a877 1573 ===============================================================================
ganlikun 0:13413ea9a877 1574 ##### Peripheral State and Errors functions #####
ganlikun 0:13413ea9a877 1575 ===============================================================================
ganlikun 0:13413ea9a877 1576 [..]
ganlikun 0:13413ea9a877 1577 This subsection permits to get in run-time the status of the peripheral
ganlikun 0:13413ea9a877 1578 and the data flow.
ganlikun 0:13413ea9a877 1579
ganlikun 0:13413ea9a877 1580 @endverbatim
ganlikun 0:13413ea9a877 1581 * @{
ganlikun 0:13413ea9a877 1582 */
ganlikun 0:13413ea9a877 1583
ganlikun 0:13413ea9a877 1584 /**
ganlikun 0:13413ea9a877 1585 * @brief Return the SAI handle state.
ganlikun 0:13413ea9a877 1586 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1587 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1588 * @retval HAL state
ganlikun 0:13413ea9a877 1589 */
ganlikun 0:13413ea9a877 1590 HAL_SAI_StateTypeDef HAL_SAI_GetState(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 1591 {
ganlikun 0:13413ea9a877 1592 return hsai->State;
ganlikun 0:13413ea9a877 1593 }
ganlikun 0:13413ea9a877 1594
ganlikun 0:13413ea9a877 1595 /**
ganlikun 0:13413ea9a877 1596 * @brief Return the SAI error code.
ganlikun 0:13413ea9a877 1597 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1598 * the configuration information for the specified SAI Block.
ganlikun 0:13413ea9a877 1599 * @retval SAI Error Code
ganlikun 0:13413ea9a877 1600 */
ganlikun 0:13413ea9a877 1601 uint32_t HAL_SAI_GetError(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 1602 {
ganlikun 0:13413ea9a877 1603 return hsai->ErrorCode;
ganlikun 0:13413ea9a877 1604 }
ganlikun 0:13413ea9a877 1605 /**
ganlikun 0:13413ea9a877 1606 * @}
ganlikun 0:13413ea9a877 1607 */
ganlikun 0:13413ea9a877 1608
ganlikun 0:13413ea9a877 1609 /**
ganlikun 0:13413ea9a877 1610 * @}
ganlikun 0:13413ea9a877 1611 */
ganlikun 0:13413ea9a877 1612
ganlikun 0:13413ea9a877 1613 /** @addtogroup SAI_Private_Functions
ganlikun 0:13413ea9a877 1614 * @brief Private functions
ganlikun 0:13413ea9a877 1615 * @{
ganlikun 0:13413ea9a877 1616 */
ganlikun 0:13413ea9a877 1617
ganlikun 0:13413ea9a877 1618 /**
ganlikun 0:13413ea9a877 1619 * @brief Initialize the SAI I2S protocol according to the specified parameters
ganlikun 0:13413ea9a877 1620 * in the SAI_InitTypeDef and create the associated handle.
ganlikun 0:13413ea9a877 1621 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1622 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1623 * @param protocol: one of the supported protocol.
ganlikun 0:13413ea9a877 1624 * @param datasize: one of the supported datasize @ref SAI_Protocol_DataSize
ganlikun 0:13413ea9a877 1625 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1626 * @param nbslot: number of slot minimum value is 2 and max is 16.
ganlikun 0:13413ea9a877 1627 * the value must be a multiple of 2.
ganlikun 0:13413ea9a877 1628 * @retval HAL status
ganlikun 0:13413ea9a877 1629 */
ganlikun 0:13413ea9a877 1630 static HAL_StatusTypeDef SAI_InitI2S(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot)
ganlikun 0:13413ea9a877 1631 {
ganlikun 0:13413ea9a877 1632 hsai->Init.Protocol = SAI_FREE_PROTOCOL;
ganlikun 0:13413ea9a877 1633 hsai->Init.FirstBit = SAI_FIRSTBIT_MSB;
ganlikun 0:13413ea9a877 1634 /* Compute ClockStrobing according AudioMode */
ganlikun 0:13413ea9a877 1635 if((hsai->Init.AudioMode == SAI_MODEMASTER_TX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX))
ganlikun 0:13413ea9a877 1636 { /* Transmit */
ganlikun 0:13413ea9a877 1637 hsai->Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
ganlikun 0:13413ea9a877 1638 }
ganlikun 0:13413ea9a877 1639 else
ganlikun 0:13413ea9a877 1640 { /* Receive */
ganlikun 0:13413ea9a877 1641 hsai->Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
ganlikun 0:13413ea9a877 1642 }
ganlikun 0:13413ea9a877 1643 hsai->FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
ganlikun 0:13413ea9a877 1644 hsai->SlotInit.SlotActive = SAI_SLOTACTIVE_ALL;
ganlikun 0:13413ea9a877 1645 hsai->SlotInit.FirstBitOffset = 0U;
ganlikun 0:13413ea9a877 1646 hsai->SlotInit.SlotNumber = nbslot;
ganlikun 0:13413ea9a877 1647
ganlikun 0:13413ea9a877 1648 /* in IS2 the number of slot must be even */
ganlikun 0:13413ea9a877 1649 if((nbslot & 0x1U) != 0U)
ganlikun 0:13413ea9a877 1650 {
ganlikun 0:13413ea9a877 1651 return HAL_ERROR;
ganlikun 0:13413ea9a877 1652 }
ganlikun 0:13413ea9a877 1653
ganlikun 0:13413ea9a877 1654 switch(protocol)
ganlikun 0:13413ea9a877 1655 {
ganlikun 0:13413ea9a877 1656 case SAI_I2S_STANDARD :
ganlikun 0:13413ea9a877 1657 hsai->FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
ganlikun 0:13413ea9a877 1658 hsai->FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
ganlikun 0:13413ea9a877 1659 break;
ganlikun 0:13413ea9a877 1660 case SAI_I2S_MSBJUSTIFIED :
ganlikun 0:13413ea9a877 1661 case SAI_I2S_LSBJUSTIFIED :
ganlikun 0:13413ea9a877 1662 hsai->FrameInit.FSPolarity = SAI_FS_ACTIVE_HIGH;
ganlikun 0:13413ea9a877 1663 hsai->FrameInit.FSOffset = SAI_FS_FIRSTBIT;
ganlikun 0:13413ea9a877 1664 break;
ganlikun 0:13413ea9a877 1665 default :
ganlikun 0:13413ea9a877 1666 return HAL_ERROR;
ganlikun 0:13413ea9a877 1667 }
ganlikun 0:13413ea9a877 1668
ganlikun 0:13413ea9a877 1669 /* Frame definition */
ganlikun 0:13413ea9a877 1670 switch(datasize)
ganlikun 0:13413ea9a877 1671 {
ganlikun 0:13413ea9a877 1672 case SAI_PROTOCOL_DATASIZE_16BIT:
ganlikun 0:13413ea9a877 1673 hsai->Init.DataSize = SAI_DATASIZE_16;
ganlikun 0:13413ea9a877 1674 hsai->FrameInit.FrameLength = 32U*(nbslot/2U);
ganlikun 0:13413ea9a877 1675 hsai->FrameInit.ActiveFrameLength = 16U*(nbslot/2U);
ganlikun 0:13413ea9a877 1676 hsai->SlotInit.SlotSize = SAI_SLOTSIZE_16B;
ganlikun 0:13413ea9a877 1677 break;
ganlikun 0:13413ea9a877 1678 case SAI_PROTOCOL_DATASIZE_16BITEXTENDED :
ganlikun 0:13413ea9a877 1679 hsai->Init.DataSize = SAI_DATASIZE_16;
ganlikun 0:13413ea9a877 1680 hsai->FrameInit.FrameLength = 64U*(nbslot/2U);
ganlikun 0:13413ea9a877 1681 hsai->FrameInit.ActiveFrameLength = 32U*(nbslot/2U);
ganlikun 0:13413ea9a877 1682 hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B;
ganlikun 0:13413ea9a877 1683 break;
ganlikun 0:13413ea9a877 1684 case SAI_PROTOCOL_DATASIZE_24BIT:
ganlikun 0:13413ea9a877 1685 hsai->Init.DataSize = SAI_DATASIZE_24;
ganlikun 0:13413ea9a877 1686 hsai->FrameInit.FrameLength = 64U*(nbslot/2U);
ganlikun 0:13413ea9a877 1687 hsai->FrameInit.ActiveFrameLength = 32U*(nbslot/2U);
ganlikun 0:13413ea9a877 1688 hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B;
ganlikun 0:13413ea9a877 1689 break;
ganlikun 0:13413ea9a877 1690 case SAI_PROTOCOL_DATASIZE_32BIT:
ganlikun 0:13413ea9a877 1691 hsai->Init.DataSize = SAI_DATASIZE_32;
ganlikun 0:13413ea9a877 1692 hsai->FrameInit.FrameLength = 64U*(nbslot/2U);
ganlikun 0:13413ea9a877 1693 hsai->FrameInit.ActiveFrameLength = 32U*(nbslot/2U);
ganlikun 0:13413ea9a877 1694 hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B;
ganlikun 0:13413ea9a877 1695 break;
ganlikun 0:13413ea9a877 1696 default :
ganlikun 0:13413ea9a877 1697 return HAL_ERROR;
ganlikun 0:13413ea9a877 1698 }
ganlikun 0:13413ea9a877 1699 if(protocol == SAI_I2S_LSBJUSTIFIED)
ganlikun 0:13413ea9a877 1700 {
ganlikun 0:13413ea9a877 1701 if (datasize == SAI_PROTOCOL_DATASIZE_16BITEXTENDED)
ganlikun 0:13413ea9a877 1702 {
ganlikun 0:13413ea9a877 1703 hsai->SlotInit.FirstBitOffset = 16U;
ganlikun 0:13413ea9a877 1704 }
ganlikun 0:13413ea9a877 1705 if (datasize == SAI_PROTOCOL_DATASIZE_24BIT)
ganlikun 0:13413ea9a877 1706 {
ganlikun 0:13413ea9a877 1707 hsai->SlotInit.FirstBitOffset = 8U;
ganlikun 0:13413ea9a877 1708 }
ganlikun 0:13413ea9a877 1709 }
ganlikun 0:13413ea9a877 1710 return HAL_OK;
ganlikun 0:13413ea9a877 1711 }
ganlikun 0:13413ea9a877 1712
ganlikun 0:13413ea9a877 1713 /**
ganlikun 0:13413ea9a877 1714 * @brief Initialize the SAI PCM protocol according to the specified parameters
ganlikun 0:13413ea9a877 1715 * in the SAI_InitTypeDef and create the associated handle.
ganlikun 0:13413ea9a877 1716 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1717 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1718 * @param protocol: one of the supported protocol
ganlikun 0:13413ea9a877 1719 * @param datasize: one of the supported datasize @ref SAI_Protocol_DataSize
ganlikun 0:13413ea9a877 1720 * @param nbslot: number of slot minimum value is 1 and the max is 16.
ganlikun 0:13413ea9a877 1721 * @retval HAL status
ganlikun 0:13413ea9a877 1722 */
ganlikun 0:13413ea9a877 1723 static HAL_StatusTypeDef SAI_InitPCM(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot)
ganlikun 0:13413ea9a877 1724 {
ganlikun 0:13413ea9a877 1725 hsai->Init.Protocol = SAI_FREE_PROTOCOL;
ganlikun 0:13413ea9a877 1726 hsai->Init.FirstBit = SAI_FIRSTBIT_MSB;
ganlikun 0:13413ea9a877 1727 /* Compute ClockStrobing according AudioMode */
ganlikun 0:13413ea9a877 1728 if((hsai->Init.AudioMode == SAI_MODEMASTER_TX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX))
ganlikun 0:13413ea9a877 1729 { /* Transmit */
ganlikun 0:13413ea9a877 1730 hsai->Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
ganlikun 0:13413ea9a877 1731 }
ganlikun 0:13413ea9a877 1732 else
ganlikun 0:13413ea9a877 1733 { /* Receive */
ganlikun 0:13413ea9a877 1734 hsai->Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
ganlikun 0:13413ea9a877 1735 }
ganlikun 0:13413ea9a877 1736 hsai->FrameInit.FSDefinition = SAI_FS_STARTFRAME;
ganlikun 0:13413ea9a877 1737 hsai->FrameInit.FSPolarity = SAI_FS_ACTIVE_HIGH;
ganlikun 0:13413ea9a877 1738 hsai->FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
ganlikun 0:13413ea9a877 1739 hsai->SlotInit.FirstBitOffset = 0U;
ganlikun 0:13413ea9a877 1740 hsai->SlotInit.SlotNumber = nbslot;
ganlikun 0:13413ea9a877 1741 hsai->SlotInit.SlotActive = SAI_SLOTACTIVE_ALL;
ganlikun 0:13413ea9a877 1742
ganlikun 0:13413ea9a877 1743 switch(protocol)
ganlikun 0:13413ea9a877 1744 {
ganlikun 0:13413ea9a877 1745 case SAI_PCM_SHORT :
ganlikun 0:13413ea9a877 1746 hsai->FrameInit.ActiveFrameLength = 1U;
ganlikun 0:13413ea9a877 1747 break;
ganlikun 0:13413ea9a877 1748 case SAI_PCM_LONG :
ganlikun 0:13413ea9a877 1749 hsai->FrameInit.ActiveFrameLength = 13U;
ganlikun 0:13413ea9a877 1750 break;
ganlikun 0:13413ea9a877 1751 default :
ganlikun 0:13413ea9a877 1752 return HAL_ERROR;
ganlikun 0:13413ea9a877 1753 }
ganlikun 0:13413ea9a877 1754
ganlikun 0:13413ea9a877 1755 switch(datasize)
ganlikun 0:13413ea9a877 1756 {
ganlikun 0:13413ea9a877 1757 case SAI_PROTOCOL_DATASIZE_16BIT:
ganlikun 0:13413ea9a877 1758 hsai->Init.DataSize = SAI_DATASIZE_16;
ganlikun 0:13413ea9a877 1759 hsai->FrameInit.FrameLength = 16U * nbslot;
ganlikun 0:13413ea9a877 1760 hsai->SlotInit.SlotSize = SAI_SLOTSIZE_16B;
ganlikun 0:13413ea9a877 1761 break;
ganlikun 0:13413ea9a877 1762 case SAI_PROTOCOL_DATASIZE_16BITEXTENDED :
ganlikun 0:13413ea9a877 1763 hsai->Init.DataSize = SAI_DATASIZE_16;
ganlikun 0:13413ea9a877 1764 hsai->FrameInit.FrameLength = 32U * nbslot;
ganlikun 0:13413ea9a877 1765 hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B;
ganlikun 0:13413ea9a877 1766 break;
ganlikun 0:13413ea9a877 1767 case SAI_PROTOCOL_DATASIZE_24BIT :
ganlikun 0:13413ea9a877 1768 hsai->Init.DataSize = SAI_DATASIZE_24;
ganlikun 0:13413ea9a877 1769 hsai->FrameInit.FrameLength = 32U * nbslot;
ganlikun 0:13413ea9a877 1770 hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B;
ganlikun 0:13413ea9a877 1771 break;
ganlikun 0:13413ea9a877 1772 case SAI_PROTOCOL_DATASIZE_32BIT:
ganlikun 0:13413ea9a877 1773 hsai->Init.DataSize = SAI_DATASIZE_32;
ganlikun 0:13413ea9a877 1774 hsai->FrameInit.FrameLength = 32U * nbslot;
ganlikun 0:13413ea9a877 1775 hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B;
ganlikun 0:13413ea9a877 1776 break;
ganlikun 0:13413ea9a877 1777 default :
ganlikun 0:13413ea9a877 1778 return HAL_ERROR;
ganlikun 0:13413ea9a877 1779 }
ganlikun 0:13413ea9a877 1780
ganlikun 0:13413ea9a877 1781 return HAL_OK;
ganlikun 0:13413ea9a877 1782 }
ganlikun 0:13413ea9a877 1783
ganlikun 0:13413ea9a877 1784 /**
ganlikun 0:13413ea9a877 1785 * @brief Fill the fifo.
ganlikun 0:13413ea9a877 1786 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1787 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1788 * @retval None
ganlikun 0:13413ea9a877 1789 */
ganlikun 0:13413ea9a877 1790 static void SAI_FillFifo(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 1791 {
ganlikun 0:13413ea9a877 1792 /* fill the fifo with data before to enabled the SAI */
ganlikun 0:13413ea9a877 1793 while(((hsai->Instance->SR & SAI_xSR_FLVL) != SAI_FIFOSTATUS_FULL) && (hsai->XferCount > 0U))
ganlikun 0:13413ea9a877 1794 {
ganlikun 0:13413ea9a877 1795 if((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
ganlikun 0:13413ea9a877 1796 {
ganlikun 0:13413ea9a877 1797 hsai->Instance->DR = (*hsai->pBuffPtr++);
ganlikun 0:13413ea9a877 1798 }
ganlikun 0:13413ea9a877 1799 else if(hsai->Init.DataSize <= SAI_DATASIZE_16)
ganlikun 0:13413ea9a877 1800 {
ganlikun 0:13413ea9a877 1801 hsai->Instance->DR = *((uint32_t *)hsai->pBuffPtr);
ganlikun 0:13413ea9a877 1802 hsai->pBuffPtr+= 2U;
ganlikun 0:13413ea9a877 1803 }
ganlikun 0:13413ea9a877 1804 else
ganlikun 0:13413ea9a877 1805 {
ganlikun 0:13413ea9a877 1806 hsai->Instance->DR = *((uint32_t *)hsai->pBuffPtr);
ganlikun 0:13413ea9a877 1807 hsai->pBuffPtr+= 4U;
ganlikun 0:13413ea9a877 1808 }
ganlikun 0:13413ea9a877 1809 hsai->XferCount--;
ganlikun 0:13413ea9a877 1810 }
ganlikun 0:13413ea9a877 1811 }
ganlikun 0:13413ea9a877 1812
ganlikun 0:13413ea9a877 1813 /**
ganlikun 0:13413ea9a877 1814 * @brief Return the interrupt flag to set according the SAI setup.
ganlikun 0:13413ea9a877 1815 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1816 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1817 * @param mode: SAI_MODE_DMA or SAI_MODE_IT
ganlikun 0:13413ea9a877 1818 * @retval the list of the IT flag to enable
ganlikun 0:13413ea9a877 1819 */
ganlikun 0:13413ea9a877 1820 static uint32_t SAI_InterruptFlag(SAI_HandleTypeDef *hsai, uint32_t mode)
ganlikun 0:13413ea9a877 1821 {
ganlikun 0:13413ea9a877 1822 uint32_t tmpIT = SAI_IT_OVRUDR;
ganlikun 0:13413ea9a877 1823
ganlikun 0:13413ea9a877 1824 if(mode == SAI_MODE_IT)
ganlikun 0:13413ea9a877 1825 {
ganlikun 0:13413ea9a877 1826 tmpIT|= SAI_IT_FREQ;
ganlikun 0:13413ea9a877 1827 }
ganlikun 0:13413ea9a877 1828
ganlikun 0:13413ea9a877 1829 if((hsai->Init.Protocol == SAI_AC97_PROTOCOL) &&
ganlikun 0:13413ea9a877 1830 ((hsai->Init.AudioMode == SAI_MODESLAVE_RX) || (hsai->Init.AudioMode == SAI_MODEMASTER_RX)))
ganlikun 0:13413ea9a877 1831 {
ganlikun 0:13413ea9a877 1832 tmpIT|= SAI_IT_CNRDY;
ganlikun 0:13413ea9a877 1833 }
ganlikun 0:13413ea9a877 1834
ganlikun 0:13413ea9a877 1835 if((hsai->Init.AudioMode == SAI_MODESLAVE_RX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX))
ganlikun 0:13413ea9a877 1836 {
ganlikun 0:13413ea9a877 1837 tmpIT|= SAI_IT_AFSDET | SAI_IT_LFSDET;
ganlikun 0:13413ea9a877 1838 }
ganlikun 0:13413ea9a877 1839 else
ganlikun 0:13413ea9a877 1840 {
ganlikun 0:13413ea9a877 1841 /* hsai has been configured in master mode */
ganlikun 0:13413ea9a877 1842 tmpIT|= SAI_IT_WCKCFG;
ganlikun 0:13413ea9a877 1843 }
ganlikun 0:13413ea9a877 1844 return tmpIT;
ganlikun 0:13413ea9a877 1845 }
ganlikun 0:13413ea9a877 1846
ganlikun 0:13413ea9a877 1847 /**
ganlikun 0:13413ea9a877 1848 * @brief Disable the SAI and wait for the disabling.
ganlikun 0:13413ea9a877 1849 * @param hsai : pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1850 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1851 * @retval None
ganlikun 0:13413ea9a877 1852 */
ganlikun 0:13413ea9a877 1853 static HAL_StatusTypeDef SAI_Disable(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 1854 {
ganlikun 0:13413ea9a877 1855 register uint32_t count = SAI_DEFAULT_TIMEOUT * (SystemCoreClock /7U/1000U);
ganlikun 0:13413ea9a877 1856 HAL_StatusTypeDef status = HAL_OK;
ganlikun 0:13413ea9a877 1857
ganlikun 0:13413ea9a877 1858 /* Disable the SAI instance */
ganlikun 0:13413ea9a877 1859 __HAL_SAI_DISABLE(hsai);
ganlikun 0:13413ea9a877 1860
ganlikun 0:13413ea9a877 1861 do
ganlikun 0:13413ea9a877 1862 {
ganlikun 0:13413ea9a877 1863 /* Check for the Timeout */
ganlikun 0:13413ea9a877 1864 if (count-- == 0U)
ganlikun 0:13413ea9a877 1865 {
ganlikun 0:13413ea9a877 1866 /* Update error code */
ganlikun 0:13413ea9a877 1867 hsai->ErrorCode |= HAL_SAI_ERROR_TIMEOUT;
ganlikun 0:13413ea9a877 1868 status = HAL_TIMEOUT;
ganlikun 0:13413ea9a877 1869 break;
ganlikun 0:13413ea9a877 1870 }
ganlikun 0:13413ea9a877 1871 } while((hsai->Instance->CR1 & SAI_xCR1_SAIEN) != RESET);
ganlikun 0:13413ea9a877 1872
ganlikun 0:13413ea9a877 1873 return status;
ganlikun 0:13413ea9a877 1874 }
ganlikun 0:13413ea9a877 1875
ganlikun 0:13413ea9a877 1876 /**
ganlikun 0:13413ea9a877 1877 * @brief Tx Handler for Transmit in Interrupt mode 8-Bit transfer.
ganlikun 0:13413ea9a877 1878 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1879 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1880 * @retval None
ganlikun 0:13413ea9a877 1881 */
ganlikun 0:13413ea9a877 1882 static void SAI_Transmit_IT8Bit(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 1883 {
ganlikun 0:13413ea9a877 1884 if(hsai->XferCount == 0U)
ganlikun 0:13413ea9a877 1885 {
ganlikun 0:13413ea9a877 1886 /* Handle the end of the transmission */
ganlikun 0:13413ea9a877 1887 /* Disable FREQ and OVRUDR interrupts */
ganlikun 0:13413ea9a877 1888 __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
ganlikun 0:13413ea9a877 1889 hsai->State = HAL_SAI_STATE_READY;
ganlikun 0:13413ea9a877 1890 HAL_SAI_TxCpltCallback(hsai);
ganlikun 0:13413ea9a877 1891 }
ganlikun 0:13413ea9a877 1892 else
ganlikun 0:13413ea9a877 1893 {
ganlikun 0:13413ea9a877 1894 /* Write data on DR register */
ganlikun 0:13413ea9a877 1895 hsai->Instance->DR = (*hsai->pBuffPtr++);
ganlikun 0:13413ea9a877 1896 hsai->XferCount--;
ganlikun 0:13413ea9a877 1897 }
ganlikun 0:13413ea9a877 1898 }
ganlikun 0:13413ea9a877 1899
ganlikun 0:13413ea9a877 1900 /**
ganlikun 0:13413ea9a877 1901 * @brief Tx Handler for Transmit in Interrupt mode for 16-Bit transfer.
ganlikun 0:13413ea9a877 1902 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1903 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1904 * @retval None
ganlikun 0:13413ea9a877 1905 */
ganlikun 0:13413ea9a877 1906 static void SAI_Transmit_IT16Bit(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 1907 {
ganlikun 0:13413ea9a877 1908 if(hsai->XferCount == 0U)
ganlikun 0:13413ea9a877 1909 {
ganlikun 0:13413ea9a877 1910 /* Handle the end of the transmission */
ganlikun 0:13413ea9a877 1911 /* Disable FREQ and OVRUDR interrupts */
ganlikun 0:13413ea9a877 1912 __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
ganlikun 0:13413ea9a877 1913 hsai->State = HAL_SAI_STATE_READY;
ganlikun 0:13413ea9a877 1914 HAL_SAI_TxCpltCallback(hsai);
ganlikun 0:13413ea9a877 1915 }
ganlikun 0:13413ea9a877 1916 else
ganlikun 0:13413ea9a877 1917 {
ganlikun 0:13413ea9a877 1918 /* Write data on DR register */
ganlikun 0:13413ea9a877 1919 hsai->Instance->DR = *(uint16_t *)hsai->pBuffPtr;
ganlikun 0:13413ea9a877 1920 hsai->pBuffPtr+=2U;
ganlikun 0:13413ea9a877 1921 hsai->XferCount--;
ganlikun 0:13413ea9a877 1922 }
ganlikun 0:13413ea9a877 1923 }
ganlikun 0:13413ea9a877 1924
ganlikun 0:13413ea9a877 1925 /**
ganlikun 0:13413ea9a877 1926 * @brief Tx Handler for Transmit in Interrupt mode for 32-Bit transfer.
ganlikun 0:13413ea9a877 1927 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1928 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1929 * @retval None
ganlikun 0:13413ea9a877 1930 */
ganlikun 0:13413ea9a877 1931 static void SAI_Transmit_IT32Bit(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 1932 {
ganlikun 0:13413ea9a877 1933 if(hsai->XferCount == 0U)
ganlikun 0:13413ea9a877 1934 {
ganlikun 0:13413ea9a877 1935 /* Handle the end of the transmission */
ganlikun 0:13413ea9a877 1936 /* Disable FREQ and OVRUDR interrupts */
ganlikun 0:13413ea9a877 1937 __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
ganlikun 0:13413ea9a877 1938 hsai->State = HAL_SAI_STATE_READY;
ganlikun 0:13413ea9a877 1939 HAL_SAI_TxCpltCallback(hsai);
ganlikun 0:13413ea9a877 1940 }
ganlikun 0:13413ea9a877 1941 else
ganlikun 0:13413ea9a877 1942 {
ganlikun 0:13413ea9a877 1943 /* Write data on DR register */
ganlikun 0:13413ea9a877 1944 hsai->Instance->DR = *(uint32_t *)hsai->pBuffPtr;
ganlikun 0:13413ea9a877 1945 hsai->pBuffPtr+=4U;
ganlikun 0:13413ea9a877 1946 hsai->XferCount--;
ganlikun 0:13413ea9a877 1947 }
ganlikun 0:13413ea9a877 1948 }
ganlikun 0:13413ea9a877 1949
ganlikun 0:13413ea9a877 1950 /**
ganlikun 0:13413ea9a877 1951 * @brief Rx Handler for Receive in Interrupt mode 8-Bit transfer.
ganlikun 0:13413ea9a877 1952 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1953 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1954 * @retval None
ganlikun 0:13413ea9a877 1955 */
ganlikun 0:13413ea9a877 1956 static void SAI_Receive_IT8Bit(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 1957 {
ganlikun 0:13413ea9a877 1958 /* Receive data */
ganlikun 0:13413ea9a877 1959 (*hsai->pBuffPtr++) = hsai->Instance->DR;
ganlikun 0:13413ea9a877 1960 hsai->XferCount--;
ganlikun 0:13413ea9a877 1961
ganlikun 0:13413ea9a877 1962 /* Check end of the transfer */
ganlikun 0:13413ea9a877 1963 if(hsai->XferCount == 0U)
ganlikun 0:13413ea9a877 1964 {
ganlikun 0:13413ea9a877 1965 /* Disable TXE and OVRUDR interrupts */
ganlikun 0:13413ea9a877 1966 __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
ganlikun 0:13413ea9a877 1967
ganlikun 0:13413ea9a877 1968 /* Clear the SAI Overrun flag */
ganlikun 0:13413ea9a877 1969 __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR);
ganlikun 0:13413ea9a877 1970
ganlikun 0:13413ea9a877 1971 hsai->State = HAL_SAI_STATE_READY;
ganlikun 0:13413ea9a877 1972 HAL_SAI_RxCpltCallback(hsai);
ganlikun 0:13413ea9a877 1973 }
ganlikun 0:13413ea9a877 1974 }
ganlikun 0:13413ea9a877 1975
ganlikun 0:13413ea9a877 1976 /**
ganlikun 0:13413ea9a877 1977 * @brief Rx Handler for Receive in Interrupt mode for 16-Bit transfer.
ganlikun 0:13413ea9a877 1978 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1979 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 1980 * @retval None
ganlikun 0:13413ea9a877 1981 */
ganlikun 0:13413ea9a877 1982 static void SAI_Receive_IT16Bit(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 1983 {
ganlikun 0:13413ea9a877 1984 /* Receive data */
ganlikun 0:13413ea9a877 1985 *(uint16_t*)hsai->pBuffPtr = hsai->Instance->DR;
ganlikun 0:13413ea9a877 1986 hsai->pBuffPtr+=2U;
ganlikun 0:13413ea9a877 1987 hsai->XferCount--;
ganlikun 0:13413ea9a877 1988
ganlikun 0:13413ea9a877 1989 /* Check end of the transfer */
ganlikun 0:13413ea9a877 1990 if(hsai->XferCount == 0U)
ganlikun 0:13413ea9a877 1991 {
ganlikun 0:13413ea9a877 1992 /* Disable TXE and OVRUDR interrupts */
ganlikun 0:13413ea9a877 1993 __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
ganlikun 0:13413ea9a877 1994
ganlikun 0:13413ea9a877 1995 /* Clear the SAI Overrun flag */
ganlikun 0:13413ea9a877 1996 __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR);
ganlikun 0:13413ea9a877 1997
ganlikun 0:13413ea9a877 1998 hsai->State = HAL_SAI_STATE_READY;
ganlikun 0:13413ea9a877 1999 HAL_SAI_RxCpltCallback(hsai);
ganlikun 0:13413ea9a877 2000 }
ganlikun 0:13413ea9a877 2001 }
ganlikun 0:13413ea9a877 2002
ganlikun 0:13413ea9a877 2003 /**
ganlikun 0:13413ea9a877 2004 * @brief Rx Handler for Receive in Interrupt mode for 32-Bit transfer.
ganlikun 0:13413ea9a877 2005 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 2006 * the configuration information for SAI module.
ganlikun 0:13413ea9a877 2007 * @retval None
ganlikun 0:13413ea9a877 2008 */
ganlikun 0:13413ea9a877 2009 static void SAI_Receive_IT32Bit(SAI_HandleTypeDef *hsai)
ganlikun 0:13413ea9a877 2010 {
ganlikun 0:13413ea9a877 2011 /* Receive data */
ganlikun 0:13413ea9a877 2012 *(uint32_t*)hsai->pBuffPtr = hsai->Instance->DR;
ganlikun 0:13413ea9a877 2013 hsai->pBuffPtr+=4U;
ganlikun 0:13413ea9a877 2014 hsai->XferCount--;
ganlikun 0:13413ea9a877 2015
ganlikun 0:13413ea9a877 2016 /* Check end of the transfer */
ganlikun 0:13413ea9a877 2017 if(hsai->XferCount == 0U)
ganlikun 0:13413ea9a877 2018 {
ganlikun 0:13413ea9a877 2019 /* Disable TXE and OVRUDR interrupts */
ganlikun 0:13413ea9a877 2020 __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
ganlikun 0:13413ea9a877 2021
ganlikun 0:13413ea9a877 2022 /* Clear the SAI Overrun flag */
ganlikun 0:13413ea9a877 2023 __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR);
ganlikun 0:13413ea9a877 2024
ganlikun 0:13413ea9a877 2025 hsai->State = HAL_SAI_STATE_READY;
ganlikun 0:13413ea9a877 2026 HAL_SAI_RxCpltCallback(hsai);
ganlikun 0:13413ea9a877 2027 }
ganlikun 0:13413ea9a877 2028 }
ganlikun 0:13413ea9a877 2029
ganlikun 0:13413ea9a877 2030 /**
ganlikun 0:13413ea9a877 2031 * @brief DMA SAI transmit process complete callback.
ganlikun 0:13413ea9a877 2032 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 2033 * the configuration information for the specified DMA module.
ganlikun 0:13413ea9a877 2034 * @retval None
ganlikun 0:13413ea9a877 2035 */
ganlikun 0:13413ea9a877 2036 static void SAI_DMATxCplt(DMA_HandleTypeDef *hdma)
ganlikun 0:13413ea9a877 2037 {
ganlikun 0:13413ea9a877 2038 SAI_HandleTypeDef* hsai = (SAI_HandleTypeDef*)((DMA_HandleTypeDef* )hdma)->Parent;
ganlikun 0:13413ea9a877 2039
ganlikun 0:13413ea9a877 2040 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
ganlikun 0:13413ea9a877 2041 {
ganlikun 0:13413ea9a877 2042 hsai->XferCount = 0U;
ganlikun 0:13413ea9a877 2043
ganlikun 0:13413ea9a877 2044 /* Disable SAI Tx DMA Request */
ganlikun 0:13413ea9a877 2045 hsai->Instance->CR1 &= (uint32_t)(~SAI_xCR1_DMAEN);
ganlikun 0:13413ea9a877 2046
ganlikun 0:13413ea9a877 2047 /* Stop the interrupts error handling */
ganlikun 0:13413ea9a877 2048 __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA));
ganlikun 0:13413ea9a877 2049
ganlikun 0:13413ea9a877 2050 hsai->State= HAL_SAI_STATE_READY;
ganlikun 0:13413ea9a877 2051 }
ganlikun 0:13413ea9a877 2052 HAL_SAI_TxCpltCallback(hsai);
ganlikun 0:13413ea9a877 2053 }
ganlikun 0:13413ea9a877 2054
ganlikun 0:13413ea9a877 2055 /**
ganlikun 0:13413ea9a877 2056 * @brief DMA SAI transmit process half complete callback.
ganlikun 0:13413ea9a877 2057 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 2058 * the configuration information for the specified DMA module.
ganlikun 0:13413ea9a877 2059 * @retval None
ganlikun 0:13413ea9a877 2060 */
ganlikun 0:13413ea9a877 2061 static void SAI_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
ganlikun 0:13413ea9a877 2062 {
ganlikun 0:13413ea9a877 2063 SAI_HandleTypeDef* hsai = (SAI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
ganlikun 0:13413ea9a877 2064
ganlikun 0:13413ea9a877 2065 HAL_SAI_TxHalfCpltCallback(hsai);
ganlikun 0:13413ea9a877 2066 }
ganlikun 0:13413ea9a877 2067
ganlikun 0:13413ea9a877 2068 /**
ganlikun 0:13413ea9a877 2069 * @brief DMA SAI receive process complete callback.
ganlikun 0:13413ea9a877 2070 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 2071 * the configuration information for the specified DMA module.
ganlikun 0:13413ea9a877 2072 * @retval None
ganlikun 0:13413ea9a877 2073 */
ganlikun 0:13413ea9a877 2074 static void SAI_DMARxCplt(DMA_HandleTypeDef *hdma)
ganlikun 0:13413ea9a877 2075 {
ganlikun 0:13413ea9a877 2076 SAI_HandleTypeDef* hsai = ( SAI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
ganlikun 0:13413ea9a877 2077 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
ganlikun 0:13413ea9a877 2078 {
ganlikun 0:13413ea9a877 2079 /* Disable Rx DMA Request */
ganlikun 0:13413ea9a877 2080 hsai->Instance->CR1 &= (uint32_t)(~SAI_xCR1_DMAEN);
ganlikun 0:13413ea9a877 2081 hsai->XferCount = 0U;
ganlikun 0:13413ea9a877 2082
ganlikun 0:13413ea9a877 2083 /* Stop the interrupts error handling */
ganlikun 0:13413ea9a877 2084 __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA));
ganlikun 0:13413ea9a877 2085
ganlikun 0:13413ea9a877 2086 hsai->State = HAL_SAI_STATE_READY;
ganlikun 0:13413ea9a877 2087 }
ganlikun 0:13413ea9a877 2088 HAL_SAI_RxCpltCallback(hsai);
ganlikun 0:13413ea9a877 2089 }
ganlikun 0:13413ea9a877 2090
ganlikun 0:13413ea9a877 2091 /**
ganlikun 0:13413ea9a877 2092 * @brief DMA SAI receive process half complete callback
ganlikun 0:13413ea9a877 2093 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 2094 * the configuration information for the specified DMA module.
ganlikun 0:13413ea9a877 2095 * @retval None
ganlikun 0:13413ea9a877 2096 */
ganlikun 0:13413ea9a877 2097 static void SAI_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
ganlikun 0:13413ea9a877 2098 {
ganlikun 0:13413ea9a877 2099 SAI_HandleTypeDef* hsai = (SAI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
ganlikun 0:13413ea9a877 2100
ganlikun 0:13413ea9a877 2101 HAL_SAI_RxHalfCpltCallback(hsai);
ganlikun 0:13413ea9a877 2102 }
ganlikun 0:13413ea9a877 2103
ganlikun 0:13413ea9a877 2104 /**
ganlikun 0:13413ea9a877 2105 * @brief DMA SAI communication error callback.
ganlikun 0:13413ea9a877 2106 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 2107 * the configuration information for the specified DMA module.
ganlikun 0:13413ea9a877 2108 * @retval None
ganlikun 0:13413ea9a877 2109 */
ganlikun 0:13413ea9a877 2110 static void SAI_DMAError(DMA_HandleTypeDef *hdma)
ganlikun 0:13413ea9a877 2111 {
ganlikun 0:13413ea9a877 2112 SAI_HandleTypeDef* hsai = ( SAI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
ganlikun 0:13413ea9a877 2113
ganlikun 0:13413ea9a877 2114 /* Set SAI error code */
ganlikun 0:13413ea9a877 2115 hsai->ErrorCode |= HAL_SAI_ERROR_DMA;
ganlikun 0:13413ea9a877 2116
ganlikun 0:13413ea9a877 2117 if((hsai->hdmatx->ErrorCode == HAL_DMA_ERROR_TE) || (hsai->hdmarx->ErrorCode == HAL_DMA_ERROR_TE))
ganlikun 0:13413ea9a877 2118 {
ganlikun 0:13413ea9a877 2119 /* Disable the SAI DMA request */
ganlikun 0:13413ea9a877 2120 hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
ganlikun 0:13413ea9a877 2121
ganlikun 0:13413ea9a877 2122 /* Disable SAI peripheral */
ganlikun 0:13413ea9a877 2123 SAI_Disable(hsai);
ganlikun 0:13413ea9a877 2124
ganlikun 0:13413ea9a877 2125 /* Set the SAI state ready to be able to start again the process */
ganlikun 0:13413ea9a877 2126 hsai->State = HAL_SAI_STATE_READY;
ganlikun 0:13413ea9a877 2127
ganlikun 0:13413ea9a877 2128 /* Initialize XferCount */
ganlikun 0:13413ea9a877 2129 hsai->XferCount = 0U;
ganlikun 0:13413ea9a877 2130 }
ganlikun 0:13413ea9a877 2131 /* SAI error Callback */
ganlikun 0:13413ea9a877 2132 HAL_SAI_ErrorCallback(hsai);
ganlikun 0:13413ea9a877 2133 }
ganlikun 0:13413ea9a877 2134
ganlikun 0:13413ea9a877 2135 /**
ganlikun 0:13413ea9a877 2136 * @brief DMA SAI Abort callback.
ganlikun 0:13413ea9a877 2137 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 2138 * the configuration information for the specified DMA module.
ganlikun 0:13413ea9a877 2139 * @retval None
ganlikun 0:13413ea9a877 2140 */
ganlikun 0:13413ea9a877 2141 static void SAI_DMAAbort(DMA_HandleTypeDef *hdma)
ganlikun 0:13413ea9a877 2142 {
ganlikun 0:13413ea9a877 2143 SAI_HandleTypeDef* hsai = ( SAI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
ganlikun 0:13413ea9a877 2144
ganlikun 0:13413ea9a877 2145 /* Disable DMA request */
ganlikun 0:13413ea9a877 2146 hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
ganlikun 0:13413ea9a877 2147
ganlikun 0:13413ea9a877 2148 /* Disable all interrupts and clear all flags */
ganlikun 0:13413ea9a877 2149 hsai->Instance->IMR = 0U;
ganlikun 0:13413ea9a877 2150 hsai->Instance->CLRFR = 0xFFFFFFFFU;
ganlikun 0:13413ea9a877 2151
ganlikun 0:13413ea9a877 2152 if(hsai->ErrorCode != HAL_SAI_ERROR_WCKCFG)
ganlikun 0:13413ea9a877 2153 {
ganlikun 0:13413ea9a877 2154 /* Disable SAI peripheral */
ganlikun 0:13413ea9a877 2155 SAI_Disable(hsai);
ganlikun 0:13413ea9a877 2156
ganlikun 0:13413ea9a877 2157 /* Flush the fifo */
ganlikun 0:13413ea9a877 2158 SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH);
ganlikun 0:13413ea9a877 2159 }
ganlikun 0:13413ea9a877 2160 /* Set the SAI state to ready to be able to start again the process */
ganlikun 0:13413ea9a877 2161 hsai->State = HAL_SAI_STATE_READY;
ganlikun 0:13413ea9a877 2162
ganlikun 0:13413ea9a877 2163 /* Initialize XferCount */
ganlikun 0:13413ea9a877 2164 hsai->XferCount = 0U;
ganlikun 0:13413ea9a877 2165
ganlikun 0:13413ea9a877 2166 /* SAI error Callback */
ganlikun 0:13413ea9a877 2167 HAL_SAI_ErrorCallback(hsai);
ganlikun 0:13413ea9a877 2168 }
ganlikun 0:13413ea9a877 2169
ganlikun 0:13413ea9a877 2170 /**
ganlikun 0:13413ea9a877 2171 * @}
ganlikun 0:13413ea9a877 2172 */
ganlikun 0:13413ea9a877 2173
ganlikun 0:13413ea9a877 2174 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx || STM32F413xx || STM32F423xx */
ganlikun 0:13413ea9a877 2175 #endif /* HAL_SAI_MODULE_ENABLED */
ganlikun 0:13413ea9a877 2176 /**
ganlikun 0:13413ea9a877 2177 * @}
ganlikun 0:13413ea9a877 2178 */
ganlikun 0:13413ea9a877 2179
ganlikun 0:13413ea9a877 2180 /**
ganlikun 0:13413ea9a877 2181 * @}
ganlikun 0:13413ea9a877 2182 */
ganlikun 0:13413ea9a877 2183
ganlikun 0:13413ea9a877 2184 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
ganlikun 0:13413ea9a877 2185