L4 HAL Drivers

Committer:
EricLew
Date:
Mon Nov 02 19:37:23 2015 +0000
Revision:
0:80ee8f3b695e
Errors are with definitions of LCD and QSPI functions. I believe all .h and .c files are  uploaded, but there may need to be certain functions called.

Who changed what in which revision?

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