inport from local

Dependents:   Hobbyking_Cheetah_0511

Committer:
NYX
Date:
Mon Mar 16 06:35:48 2020 +0000
Revision:
0:85b3fd62ea1a
reinport to mbed;

Who changed what in which revision?

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