L4 HAL Drivers
Embed:
(wiki syntax)
Show/hide line numbers
stm32l4xx_hal_sai.c
Go to the documentation of this file.
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_hal_sai.c 00004 * @author MCD Application Team 00005 * @version V1.1.0 00006 * @date 16-September-2015 00007 * @brief SAI HAL module driver. 00008 * This file provides firmware functions to manage the following 00009 * functionalities of the Serial Audio Interface (SAI) peripheral: 00010 * + Initialization/de-initialization functions 00011 * + I/O operation functions 00012 * + Peripheral Control functions 00013 * + Peripheral State functions 00014 * 00015 @verbatim 00016 ============================================================================== 00017 ##### How to use this driver ##### 00018 ============================================================================== 00019 [..] 00020 The SAI HAL driver can be used as follows: 00021 00022 (#) Declare a SAI_HandleTypeDef handle structure (eg. SAI_HandleTypeDef hsai). 00023 (#) Initialize the SAI low level resources by implementing the HAL_SAI_MspInit() API: 00024 (##) Enable the SAI interface clock. 00025 (##) SAI pins configuration: 00026 (+++) Enable the clock for the SAI GPIOs. 00027 (+++) Configure these SAI pins as alternate function pull-up. 00028 (##) NVIC configuration if you need to use interrupt process (HAL_SAI_Transmit_IT() 00029 and HAL_SAI_Receive_IT() APIs): 00030 (+++) Configure the SAI interrupt priority. 00031 (+++) Enable the NVIC SAI IRQ handle. 00032 00033 (##) DMA Configuration if you need to use DMA process (HAL_SAI_Transmit_DMA() 00034 and HAL_SAI_Receive_DMA() APIs): 00035 (+++) Declare a DMA handle structure for the Tx/Rx channel. 00036 (+++) Enable the DMAx interface clock. 00037 (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters. 00038 (+++) Configure the DMA Tx/Rx Channel. 00039 (+++) Associate the initialized DMA handle to the SAI DMA Tx/Rx handle. 00040 (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the 00041 DMA Tx/Rx Channel. 00042 00043 (#) The initialization can be done by two ways 00044 (##) Expert mode : Initialize the structures Init, FrameInit and SlotInit and call HAL_SAI_Init(). 00045 (##) Simplified mode : Initialize the high part of Init Structure and call HAL_SAI_InitProtocol(). 00046 00047 [..] 00048 (@) The specific SAI interrupts (FIFO request and Overrun underrun interrupt) 00049 will be managed using the macros __HAL_SAI_ENABLE_IT() and __HAL_SAI_DISABLE_IT() 00050 inside the transmit and receive process. 00051 00052 [..] 00053 (@) Make sure that either: 00054 (+@) PLLSAI1CLK output is configured or 00055 (+@) PLLSAI2CLK output is configured or 00056 (+@) PLLSAI3CLK output is configured or 00057 (+@) External clock source is configured after setting correctly 00058 the define constant EXTERNAL_SAI1_CLOCK_VALUE or EXTERNAL_SAI2_CLOCK_VALUE in the stm32l4xx_hal_conf.h file. 00059 00060 [..] 00061 (@) In master Tx mode: enabling the audio block immediately generates the bit clock 00062 for the external slaves even if there is no data in the FIFO, However FS signal 00063 generation is conditioned by the presence of data in the FIFO. 00064 00065 [..] 00066 (@) In master Rx mode: enabling the audio block immediately generates the bit clock 00067 and FS signal for the external slaves. 00068 00069 [..] 00070 (@) It is mandatory to respect the following conditions in order to avoid bad SAI behavior: 00071 (+@) First bit Offset <= (SLOT size - Data size) 00072 (+@) Data size <= SLOT size 00073 (+@) Number of SLOT x SLOT size = Frame length 00074 (+@) The number of slots should be even when SAI_FS_CHANNEL_IDENTIFICATION is selected. 00075 00076 [..] 00077 Three operation modes are available within this driver : 00078 00079 *** Polling mode IO operation *** 00080 ================================= 00081 [..] 00082 (+) Send an amount of data in blocking mode using HAL_SAI_Transmit() 00083 (+) Receive an amount of data in blocking mode using HAL_SAI_Receive() 00084 00085 *** Interrupt mode IO operation *** 00086 =================================== 00087 [..] 00088 (+) Send an amount of data in non-blocking mode using HAL_SAI_Transmit_IT() 00089 (+) At transmission end of transfer HAL_SAI_TxCpltCallback() is executed and user can 00090 add his own code by customization of function pointer HAL_SAI_TxCpltCallback() 00091 (+) Receive an amount of data in non-blocking mode using HAL_SAI_Receive_IT() 00092 (+) At reception end of transfer HAL_SAI_RxCpltCallback() is executed and user can 00093 add his own code by customization of function pointer HAL_SAI_RxCpltCallback() 00094 (+) In case of flag error, HAL_SAI_ErrorCallback() function is executed and user can 00095 add his own code by customization of function pointer HAL_SAI_ErrorCallback() 00096 00097 *** DMA mode IO operation *** 00098 ============================== 00099 [..] 00100 (+) Send an amount of data in non-blocking mode (DMA) using HAL_SAI_Transmit_DMA() 00101 (+) At transmission end of transfer HAL_SAI_TxCpltCallback() is executed and user can 00102 add his own code by customization of function pointer HAL_SAI_TxCpltCallback() 00103 (+) Receive an amount of data in non-blocking mode (DMA) using HAL_SAI_Receive_DMA() 00104 (+) At reception end of transfer HAL_SAI_RxCpltCallback() is executed and user can 00105 add his own code by customization of function pointer HAL_SAI_RxCpltCallback() 00106 (+) In case of flag error, HAL_SAI_ErrorCallback() function is executed and user can 00107 add his own code by customization of function pointer HAL_SAI_ErrorCallback() 00108 (+) Pause the DMA Transfer using HAL_SAI_DMAPause() 00109 (+) Resume the DMA Transfer using HAL_SAI_DMAResume() 00110 (+) Stop the DMA Transfer using HAL_SAI_DMAStop() 00111 00112 *** SAI HAL driver additional function list *** 00113 ================================================= 00114 [..] 00115 Below the list the others API available SAI HAL driver : 00116 00117 (+) HAL_SAI_EnableTxMuteMode(): Enable the mute in tx mode 00118 (+) HAL_SAI_DisableTxMuteMode(): Disable the mute in tx mode 00119 (+) HAL_SAI_EnableRxMuteMode(): Enable the mute in Rx mode 00120 (+) HAL_SAI_DisableRxMuteMode(): Disable the mute in Rx mode 00121 (+) HAL_SAI_FlushRxFifo(): Flush the rx fifo. 00122 (+) HAL_SAI_Abort(): Abort the current transfer 00123 00124 *** SAI HAL driver macros list *** 00125 ============================================= 00126 [..] 00127 Below the list of most used macros in SAI HAL driver : 00128 00129 (+) __HAL_SAI_ENABLE(): Enable the SAI peripheral 00130 (+) __HAL_SAI_DISABLE(): Disable the SAI peripheral 00131 (+) __HAL_SAI_ENABLE_IT(): Enable the specified SAI interrupts 00132 (+) __HAL_SAI_DISABLE_IT(): Disable the specified SAI interrupts 00133 (+) __HAL_SAI_GET_IT_SOURCE(): Check if the specified SAI interrupt source is 00134 enabled or disabled 00135 (+) __HAL_SAI_GET_FLAG(): Check whether the specified SAI flag is set or not 00136 00137 @endverbatim 00138 ****************************************************************************** 00139 * @attention 00140 * 00141 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> 00142 * 00143 * Redistribution and use in source and binary forms, with or without modification, 00144 * are permitted provided that the following conditions are met: 00145 * 1. Redistributions of source code must retain the above copyright notice, 00146 * this list of conditions and the following disclaimer. 00147 * 2. Redistributions in binary form must reproduce the above copyright notice, 00148 * this list of conditions and the following disclaimer in the documentation 00149 * and/or other materials provided with the distribution. 00150 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00151 * may be used to endorse or promote products derived from this software 00152 * without specific prior written permission. 00153 * 00154 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00155 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00156 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00157 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00158 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00159 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00160 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00161 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00162 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00163 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00164 * 00165 ****************************************************************************** 00166 */ 00167 00168 /* Includes ------------------------------------------------------------------*/ 00169 #include "stm32l4xx_hal.h" 00170 00171 /** @addtogroup STM32L4xx_HAL_Driver 00172 * @{ 00173 */ 00174 00175 /** @defgroup SAI SAI 00176 * @brief SAI HAL module driver 00177 * @{ 00178 */ 00179 00180 #ifdef HAL_SAI_MODULE_ENABLED 00181 00182 /* Private typedef -----------------------------------------------------------*/ 00183 /** @defgroup SAI_Private_Typedefs SAI Private Typedefs 00184 * @{ 00185 */ 00186 typedef enum { 00187 SAI_MODE_DMA, 00188 SAI_MODE_IT 00189 }SAI_ModeTypedef; 00190 /** 00191 * @} 00192 */ 00193 00194 /* Private define ------------------------------------------------------------*/ 00195 /** @defgroup SAI_Private_Constants SAI Private Constants 00196 * @{ 00197 */ 00198 #define SAI_FIFO_SIZE 8 00199 #define SAI_DEFAULT_TIMEOUT 4 00200 /** 00201 * @} 00202 */ 00203 00204 /* Private macro -------------------------------------------------------------*/ 00205 /* Private variables ---------------------------------------------------------*/ 00206 /* Private function prototypes -----------------------------------------------*/ 00207 /** @defgroup SAI_Private_Functions SAI Private Functions 00208 * @{ 00209 */ 00210 static void SAI_FillFifo(SAI_HandleTypeDef *hsai); 00211 static int32_t SAI_InterruptFlag(SAI_HandleTypeDef *hsai, uint32_t mode); 00212 static HAL_StatusTypeDef SAI_InitI2S(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot); 00213 static HAL_StatusTypeDef SAI_InitPCM(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot); 00214 00215 static HAL_StatusTypeDef SAI_Disable(SAI_HandleTypeDef *hsai); 00216 static void SAI_Transmit_IT8Bit(SAI_HandleTypeDef *hsai); 00217 static void SAI_Transmit_IT16Bit(SAI_HandleTypeDef *hsai); 00218 static void SAI_Transmit_IT32Bit(SAI_HandleTypeDef *hsai); 00219 static void SAI_Receive_IT8Bit(SAI_HandleTypeDef *hsai); 00220 static void SAI_Receive_IT16Bit(SAI_HandleTypeDef *hsai); 00221 static void SAI_Receive_IT32Bit(SAI_HandleTypeDef *hsai); 00222 static void SAI_DMATxCplt(DMA_HandleTypeDef *hdma); 00223 static void SAI_DMATxHalfCplt(DMA_HandleTypeDef *hdma); 00224 static void SAI_DMARxCplt(DMA_HandleTypeDef *hdma); 00225 static void SAI_DMARxHalfCplt(DMA_HandleTypeDef *hdma); 00226 static void SAI_DMAError(DMA_HandleTypeDef *hdma); 00227 /** 00228 * @} 00229 */ 00230 00231 /* Exported functions --------------------------------------------------------*/ 00232 00233 /** @defgroup SAI_Exported_Functions SAI Exported Functions 00234 * @{ 00235 */ 00236 00237 /** @defgroup SAI_Exported_Functions_Group1 Initialization and de-initialization functions 00238 * @brief Initialization and Configuration functions 00239 * 00240 @verbatim 00241 =============================================================================== 00242 ##### Initialization and de-initialization functions ##### 00243 =============================================================================== 00244 [..] This subsection provides a set of functions allowing to initialize and 00245 de-initialize the SAIx peripheral: 00246 00247 (+) User must implement HAL_SAI_MspInit() function in which he configures 00248 all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ). 00249 00250 (+) Call the function HAL_SAI_Init() to configure the selected device with 00251 the selected configuration: 00252 (++) Mode (Master/slave TX/RX) 00253 (++) Protocol 00254 (++) Data Size 00255 (++) MCLK Output 00256 (++) Audio frequency 00257 (++) FIFO Threshold 00258 (++) Frame Config 00259 (++) Slot Config 00260 00261 (+) Call the function HAL_SAI_DeInit() to restore the default configuration 00262 of the selected SAI peripheral. 00263 00264 @endverbatim 00265 * @{ 00266 */ 00267 00268 /** 00269 * @brief Initialize the structure FrameInit, SlotInit and the low part of 00270 * Init according to the specified parameters and call the function 00271 * HAL_SAI_Init to initialize the SAI block. 00272 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 00273 * the configuration information for SAI module. 00274 * @param protocol: one of the supported protocol @ref SAI_Protocol 00275 * @param datasize: one of the supported datasize @ref SAI_Protocol_DataSize 00276 * the configuration information for SAI module. 00277 * @param nbslot: Number of slot. 00278 * @retval HAL status 00279 */ 00280 HAL_StatusTypeDef HAL_SAI_InitProtocol(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot) 00281 { 00282 HAL_StatusTypeDef errorcode = HAL_OK; 00283 00284 switch(protocol) 00285 { 00286 case SAI_I2S_STANDARD : 00287 case SAI_I2S_MSBJUSTIFIED : 00288 case SAI_I2S_LSBJUSTIFIED : 00289 errorcode = SAI_InitI2S(hsai, protocol, datasize, nbslot); 00290 break; 00291 case SAI_PCM_LONG : 00292 case SAI_PCM_SHORT : 00293 errorcode = SAI_InitPCM(hsai, protocol, datasize, nbslot); 00294 break; 00295 default : 00296 errorcode = HAL_ERROR; 00297 break; 00298 } 00299 00300 if(errorcode == HAL_OK) 00301 { 00302 errorcode = HAL_SAI_Init(hsai); 00303 } 00304 00305 return errorcode; 00306 } 00307 00308 /** 00309 * @brief Initialize the SAI according to the specified parameters 00310 * in the SAI_InitTypeDef structure and initialize the associated handle. 00311 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 00312 * the configuration information for SAI module. 00313 * @retval HAL status 00314 */ 00315 HAL_StatusTypeDef HAL_SAI_Init(SAI_HandleTypeDef *hsai) 00316 { 00317 uint32_t tmpregisterGCR = 0; 00318 00319 /* Check the SAI handle allocation */ 00320 if(hsai == NULL) 00321 { 00322 return HAL_ERROR; 00323 } 00324 00325 /* check the instance */ 00326 assert_param(IS_SAI_ALL_INSTANCE(hsai->Instance)); 00327 00328 /* Check the SAI Block parameters */ 00329 assert_param(IS_SAI_AUDIO_FREQUENCY(hsai->Init.AudioFrequency)); 00330 assert_param(IS_SAI_BLOCK_PROTOCOL(hsai->Init.Protocol)); 00331 assert_param(IS_SAI_BLOCK_MODE(hsai->Init.AudioMode)); 00332 assert_param(IS_SAI_BLOCK_DATASIZE(hsai->Init.DataSize)); 00333 assert_param(IS_SAI_BLOCK_FIRST_BIT(hsai->Init.FirstBit)); 00334 assert_param(IS_SAI_BLOCK_CLOCK_STROBING(hsai->Init.ClockStrobing)); 00335 assert_param(IS_SAI_BLOCK_SYNCHRO(hsai->Init.Synchro)); 00336 assert_param(IS_SAI_BLOCK_OUTPUT_DRIVE(hsai->Init.OutputDrive)); 00337 assert_param(IS_SAI_BLOCK_NODIVIDER(hsai->Init.NoDivider)); 00338 assert_param(IS_SAI_BLOCK_FIFO_THRESHOLD(hsai->Init.FIFOThreshold)); 00339 assert_param(IS_SAI_MONOSTEREO_MODE(hsai->Init.MonoStereoMode)); 00340 assert_param(IS_SAI_BLOCK_COMPANDING_MODE(hsai->Init.CompandingMode)); 00341 assert_param(IS_SAI_BLOCK_TRISTATE_MANAGEMENT(hsai->Init.TriState)); 00342 assert_param(IS_SAI_BLOCK_SYNCEXT(hsai->Init.SynchroExt)); 00343 00344 /* Check the SAI Block Frame parameters */ 00345 assert_param(IS_SAI_BLOCK_FRAME_LENGTH(hsai->FrameInit.FrameLength)); 00346 assert_param(IS_SAI_BLOCK_ACTIVE_FRAME(hsai->FrameInit.ActiveFrameLength)); 00347 assert_param(IS_SAI_BLOCK_FS_DEFINITION(hsai->FrameInit.FSDefinition)); 00348 assert_param(IS_SAI_BLOCK_FS_POLARITY(hsai->FrameInit.FSPolarity)); 00349 assert_param(IS_SAI_BLOCK_FS_OFFSET(hsai->FrameInit.FSOffset)); 00350 00351 /* Check the SAI Block Slot parameters */ 00352 assert_param(IS_SAI_BLOCK_FIRSTBIT_OFFSET(hsai->SlotInit.FirstBitOffset)); 00353 assert_param(IS_SAI_BLOCK_SLOT_SIZE(hsai->SlotInit.SlotSize)); 00354 assert_param(IS_SAI_BLOCK_SLOT_NUMBER(hsai->SlotInit.SlotNumber)); 00355 assert_param(IS_SAI_SLOT_ACTIVE(hsai->SlotInit.SlotActive)); 00356 00357 if(hsai->State == HAL_SAI_STATE_RESET) 00358 { 00359 /* Allocate lock resource and initialize it */ 00360 hsai->Lock = HAL_UNLOCKED; 00361 00362 /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ 00363 HAL_SAI_MspInit(hsai); 00364 } 00365 00366 hsai->State = HAL_SAI_STATE_BUSY; 00367 00368 /* Disable the selected SAI peripheral */ 00369 SAI_Disable(hsai); 00370 00371 /* SAI Block Synchro Configuration ---------------------------------------------------*/ 00372 /* This setting must be done with both audio block (A & B) disabled */ 00373 switch(hsai->Init.SynchroExt) 00374 { 00375 case SAI_SYNCEXT_DISABLE : 00376 tmpregisterGCR = 0; 00377 break; 00378 case SAI_SYNCEXT_IN_ENABLE : 00379 tmpregisterGCR = SAI_GCR_SYNCIN_0; 00380 break; 00381 case SAI_SYNCEXT_OUTBLOCKA_ENABLE : 00382 tmpregisterGCR = SAI_GCR_SYNCOUT_0; 00383 break; 00384 case SAI_SYNCEXT_OUTBLOCKB_ENABLE : 00385 tmpregisterGCR = SAI_GCR_SYNCOUT_1; 00386 break; 00387 } 00388 00389 if((hsai->Instance == SAI1_Block_A) || (hsai->Instance == SAI1_Block_B)) 00390 { 00391 SAI1->GCR = tmpregisterGCR; 00392 } 00393 else 00394 { 00395 SAI2->GCR = tmpregisterGCR; 00396 } 00397 00398 if(hsai->Init.AudioFrequency != SAI_AUDIO_FREQUENCY_MCKDIV) 00399 { 00400 uint32_t freq = 0; 00401 uint32_t tmpval; 00402 /* In this case, the MCKDIV value is calculated to get AudioFrequency */ 00403 if((hsai->Instance == SAI1_Block_A ) || (hsai->Instance == SAI1_Block_B )) 00404 { 00405 freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SAI1); 00406 } 00407 if((hsai->Instance == SAI2_Block_A ) || (hsai->Instance == SAI2_Block_B )) 00408 { 00409 freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SAI2); 00410 } 00411 00412 /* Configure Master Clock using the following formula : 00413 MCLK_x = SAI_CK_x / (MCKDIV[3:0] * 2) with MCLK_x = 256 * FS 00414 FS = SAI_CK_x / (MCKDIV[3:0] * 2) * 256 00415 MCKDIV[3:0] = SAI_CK_x / FS * 512 */ 00416 /* (freq x 10) to keep Significant digits */ 00417 tmpval = (freq * 10) / (hsai->Init.AudioFrequency * 2 * 256); 00418 hsai->Init.Mckdiv = tmpval / 10; 00419 00420 /* Round result to the nearest integer */ 00421 if((tmpval % 10) > 8) 00422 { 00423 hsai->Init.Mckdiv+= 1; 00424 } 00425 } 00426 00427 /* SAI Block Configuration ------------------------------------------------------------*/ 00428 /* SAI CR1 Configuration */ 00429 hsai->Instance->CR1&=~(SAI_xCR1_MODE | SAI_xCR1_PRTCFG | SAI_xCR1_DS | \ 00430 SAI_xCR1_LSBFIRST | SAI_xCR1_CKSTR | SAI_xCR1_SYNCEN |\ 00431 SAI_xCR1_MONO | SAI_xCR1_OUTDRIV | SAI_xCR1_DMAEN | \ 00432 SAI_xCR1_NODIV | SAI_xCR1_MCKDIV); 00433 00434 hsai->Instance->CR1|=(hsai->Init.AudioMode | hsai->Init.Protocol | \ 00435 hsai->Init.DataSize | hsai->Init.FirstBit | \ 00436 hsai->Init.ClockStrobing | hsai->Init.Synchro | \ 00437 hsai->Init.MonoStereoMode | hsai->Init.OutputDrive | \ 00438 hsai->Init.NoDivider | (hsai->Init.Mckdiv << 20) | hsai->Init.CompandingMode); 00439 00440 /* SAI CR2 Configuration */ 00441 hsai->Instance->CR2&= ~(SAI_xCR2_FTH | SAI_xCR2_FFLUSH | SAI_xCR2_COMP); 00442 hsai->Instance->CR2|= (hsai->Init.FIFOThreshold | hsai->Init.CompandingMode | hsai->Init.TriState); 00443 00444 00445 /* SAI Frame Configuration -----------------------------------------*/ 00446 hsai->Instance->FRCR&=(~(SAI_xFRCR_FRL | SAI_xFRCR_FSALL | SAI_xFRCR_FSDEF | \ 00447 SAI_xFRCR_FSPO | SAI_xFRCR_FSOFF)); 00448 hsai->Instance->FRCR|=((hsai->FrameInit.FrameLength - 1) | 00449 hsai->FrameInit.FSOffset | 00450 hsai->FrameInit.FSDefinition | 00451 hsai->FrameInit.FSPolarity | 00452 ((hsai->FrameInit.ActiveFrameLength - 1) << 8)); 00453 00454 /* SAI Block_x SLOT Configuration ------------------------------------------*/ 00455 /* This register has no meaning in AC 97 and SPDIF audio protocol */ 00456 hsai->Instance->SLOTR&= (~(SAI_xSLOTR_FBOFF | SAI_xSLOTR_SLOTSZ | \ 00457 SAI_xSLOTR_NBSLOT | SAI_xSLOTR_SLOTEN )); 00458 00459 hsai->Instance->SLOTR|= hsai->SlotInit.FirstBitOffset | hsai->SlotInit.SlotSize 00460 | hsai->SlotInit.SlotActive | ((hsai->SlotInit.SlotNumber - 1) << 8); 00461 00462 /* Initialize the error code */ 00463 hsai->ErrorCode = HAL_SAI_ERROR_NONE; 00464 00465 /* Initialize the SAI state */ 00466 hsai->State= HAL_SAI_STATE_READY; 00467 00468 /* Release Lock */ 00469 __HAL_UNLOCK(hsai); 00470 00471 return HAL_OK; 00472 } 00473 00474 /** 00475 * @brief DeInitialize the SAI peripheral. 00476 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 00477 * the configuration information for SAI module. 00478 * @retval HAL status 00479 */ 00480 HAL_StatusTypeDef HAL_SAI_DeInit(SAI_HandleTypeDef *hsai) 00481 { 00482 /* Check the SAI handle allocation */ 00483 if(hsai == NULL) 00484 { 00485 return HAL_ERROR; 00486 } 00487 00488 hsai->State = HAL_SAI_STATE_BUSY; 00489 00490 /* Disabled All interrupt and clear all the flag */ 00491 hsai->Instance->IMR = 0; 00492 hsai->Instance->CLRFR = 0xFFFFFFFF; 00493 00494 /* Disable the SAI */ 00495 SAI_Disable(hsai); 00496 00497 /* Flush the fifo */ 00498 SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH); 00499 00500 /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */ 00501 HAL_SAI_MspDeInit(hsai); 00502 00503 /* Initialize the error code */ 00504 hsai->ErrorCode = HAL_SAI_ERROR_NONE; 00505 00506 /* Initialize the SAI state */ 00507 hsai->State = HAL_SAI_STATE_RESET; 00508 00509 return HAL_OK; 00510 } 00511 00512 /** 00513 * @brief Initialize the SAI MSP. 00514 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 00515 * the configuration information for SAI module. 00516 * @retval None 00517 */ 00518 __weak void HAL_SAI_MspInit(SAI_HandleTypeDef *hsai) 00519 { 00520 /* NOTE : This function should not be modified, when the callback is needed, 00521 the HAL_SAI_MspInit could be implemented in the user file 00522 */ 00523 } 00524 00525 /** 00526 * @brief DeInitialize the SAI MSP. 00527 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 00528 * the configuration information for SAI module. 00529 * @retval None 00530 */ 00531 __weak void HAL_SAI_MspDeInit(SAI_HandleTypeDef *hsai) 00532 { 00533 /* NOTE : This function should not be modified, when the callback is needed, 00534 the HAL_SAI_MspDeInit could be implemented in the user file 00535 */ 00536 } 00537 00538 /** 00539 * @} 00540 */ 00541 00542 /** @defgroup SAI_Exported_Functions_Group2 IO operation functions 00543 * @brief Data transfers functions 00544 * 00545 @verbatim 00546 =============================================================================== 00547 ##### IO operation functions ##### 00548 =============================================================================== 00549 [..] 00550 This subsection provides a set of functions allowing to manage the SAI data 00551 transfers. 00552 00553 (+) There are two modes of transfer: 00554 (++) Blocking mode : The communication is performed in the polling mode. 00555 The status of all data processing is returned by the same function 00556 after finishing transfer. 00557 (++) No-Blocking mode : The communication is performed using Interrupts 00558 or DMA. These functions return the status of the transfer startup. 00559 The end of the data processing will be indicated through the 00560 dedicated SAI IRQ when using Interrupt mode or the DMA IRQ when 00561 using DMA mode. 00562 00563 (+) Blocking mode functions are : 00564 (++) HAL_SAI_Transmit() 00565 (++) HAL_SAI_Receive() 00566 (++) HAL_SAI_TransmitReceive() 00567 00568 (+) Non Blocking mode functions with Interrupt are : 00569 (++) HAL_SAI_Transmit_IT() 00570 (++) HAL_SAI_Receive_IT() 00571 (++) HAL_SAI_TransmitReceive_IT() 00572 00573 (+) Non Blocking mode functions with DMA are : 00574 (++) HAL_SAI_Transmit_DMA() 00575 (++) HAL_SAI_Receive_DMA() 00576 (++) HAL_SAI_TransmitReceive_DMA() 00577 00578 (+) A set of Transfer Complete Callbacks are provided in non Blocking mode: 00579 (++) HAL_SAI_TxCpltCallback() 00580 (++) HAL_SAI_RxCpltCallback() 00581 (++) HAL_SAI_ErrorCallback() 00582 00583 @endverbatim 00584 * @{ 00585 */ 00586 00587 /** 00588 * @brief Transmit an amount of data in blocking mode. 00589 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 00590 * the configuration information for SAI module. 00591 * @param pData: Pointer to data buffer 00592 * @param Size: Amount of data to be sent 00593 * @param Timeout: Timeout duration 00594 * @retval HAL status 00595 */ 00596 HAL_StatusTypeDef HAL_SAI_Transmit(SAI_HandleTypeDef *hsai, uint8_t* pData, uint16_t Size, uint32_t Timeout) 00597 { 00598 uint32_t tickstart = HAL_GetTick(); 00599 HAL_StatusTypeDef errorcode = HAL_OK; 00600 00601 /* Process Locked */ 00602 __HAL_LOCK(hsai); 00603 00604 if((pData == NULL ) || (Size == 0)) 00605 { 00606 errorcode = HAL_ERROR; 00607 goto error; 00608 } 00609 00610 if(hsai->State != HAL_SAI_STATE_READY) 00611 { 00612 errorcode = HAL_BUSY; 00613 goto error; 00614 } 00615 00616 hsai->State = HAL_SAI_STATE_BUSY_TX; 00617 hsai->ErrorCode = HAL_SAI_ERROR_NONE; 00618 hsai->XferSize = Size; 00619 hsai->XferCount = Size; 00620 hsai->pBuffPtr = pData; 00621 00622 /* Check if the SAI is already enabled */ 00623 if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET) 00624 { 00625 /* fill the fifo with data before to enabled the SAI */ 00626 SAI_FillFifo(hsai); 00627 /* Enable SAI peripheral */ 00628 __HAL_SAI_ENABLE(hsai); 00629 } 00630 00631 do 00632 { 00633 /* Write data if the FIFO is not full */ 00634 if((hsai->Instance->SR & SAI_xSR_FLVL) != SAI_FIFOSTATUS_FULL) 00635 { 00636 if((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING)) 00637 { 00638 hsai->Instance->DR = (*hsai->pBuffPtr++); 00639 } 00640 else if(hsai->Init.DataSize <= SAI_DATASIZE_16) 00641 { 00642 *(uint16_t *)&hsai->Instance->DR = *((uint16_t *)hsai->pBuffPtr); 00643 hsai->pBuffPtr+= 2; 00644 } 00645 else 00646 { 00647 hsai->Instance->DR = *((uint32_t *)hsai->pBuffPtr); 00648 hsai->pBuffPtr+= 4; 00649 } 00650 hsai->XferCount--; 00651 } 00652 else 00653 { 00654 /* Check for the Timeout */ 00655 if((Timeout != HAL_MAX_DELAY) && ((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))) 00656 { 00657 errorcode = HAL_TIMEOUT; 00658 goto error; 00659 } 00660 } 00661 } 00662 while(0 != hsai->XferCount); 00663 00664 error : 00665 hsai->State = HAL_SAI_STATE_READY; 00666 /* Process Unlocked */ 00667 __HAL_UNLOCK(hsai); 00668 return errorcode; 00669 } 00670 00671 /** 00672 * @brief Receive an amount of data in blocking mode. 00673 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 00674 * the configuration information for SAI module. 00675 * @param pData: Pointer to data buffer 00676 * @param Size: Amount of data to be received 00677 * @param Timeout: Timeout duration 00678 * @retval HAL status 00679 */ 00680 HAL_StatusTypeDef HAL_SAI_Receive(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size, uint32_t Timeout) 00681 { 00682 uint32_t tickstart = HAL_GetTick(); 00683 HAL_StatusTypeDef errorcode = HAL_OK; 00684 00685 /* Process Locked */ 00686 __HAL_LOCK(hsai); 00687 00688 if((pData == NULL ) || (Size == 0)) 00689 { 00690 errorcode = HAL_ERROR; 00691 goto error; 00692 } 00693 00694 if(hsai->State != HAL_SAI_STATE_READY) 00695 { 00696 errorcode = HAL_BUSY; 00697 goto error; 00698 } 00699 00700 hsai->pBuffPtr = pData; 00701 hsai->XferSize = Size; 00702 hsai->XferCount = Size; 00703 hsai->State = HAL_SAI_STATE_BUSY_RX; 00704 hsai->ErrorCode = HAL_SAI_ERROR_NONE; 00705 00706 /* Check if the SAI is already enabled */ 00707 if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET) 00708 { 00709 /* Enable SAI peripheral */ 00710 __HAL_SAI_ENABLE(hsai); 00711 } 00712 00713 /* Receive data */ 00714 do 00715 { 00716 /* Wait until RXNE flag is set */ 00717 if((hsai->Instance->SR & SAI_xSR_FLVL) != SAI_FIFOSTATUS_EMPTY) 00718 { 00719 if((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING)) 00720 { 00721 (*hsai->pBuffPtr++) = hsai->Instance->DR; 00722 } 00723 else if(hsai->Init.DataSize <= SAI_DATASIZE_16) 00724 { 00725 *((uint16_t*)hsai->pBuffPtr) = hsai->Instance->DR; 00726 hsai->pBuffPtr+= 2; 00727 } 00728 else 00729 { 00730 *((uint32_t*)hsai->pBuffPtr) = hsai->Instance->DR; 00731 hsai->pBuffPtr+= 4; 00732 } 00733 hsai->XferCount--; 00734 } 00735 else 00736 { 00737 /* Check for the Timeout */ 00738 if((Timeout != HAL_MAX_DELAY) && ((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))) 00739 { 00740 errorcode = HAL_TIMEOUT; 00741 goto error; 00742 } 00743 } 00744 } 00745 while(0 != hsai->XferCount); 00746 00747 error : 00748 hsai->State = HAL_SAI_STATE_READY; 00749 /* Process Unlocked */ 00750 __HAL_UNLOCK(hsai); 00751 return errorcode; 00752 } 00753 00754 /** 00755 * @brief Transmit an amount of data in non-blocking mode with Interrupt. 00756 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 00757 * the configuration information for SAI module. 00758 * @param pData: Pointer to data buffer 00759 * @param Size: Amount of data to be sent 00760 * @retval HAL status 00761 */ 00762 HAL_StatusTypeDef HAL_SAI_Transmit_IT(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size) 00763 { 00764 HAL_StatusTypeDef errorcode = HAL_OK; 00765 00766 /* Process Locked */ 00767 __HAL_LOCK(hsai); 00768 00769 if((pData == NULL) || (Size == 0)) 00770 { 00771 errorcode = HAL_ERROR; 00772 goto error; 00773 } 00774 00775 if(hsai->State != HAL_SAI_STATE_READY) 00776 { 00777 errorcode = HAL_BUSY; 00778 goto error; 00779 } 00780 00781 hsai->pBuffPtr = pData; 00782 hsai->XferSize = Size; 00783 hsai->XferCount = Size; 00784 hsai->ErrorCode = HAL_SAI_ERROR_NONE; 00785 hsai->State = HAL_SAI_STATE_BUSY_TX; 00786 if((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING)) 00787 { 00788 hsai->InterruptServiceRoutine = SAI_Transmit_IT8Bit; 00789 } 00790 else if(hsai->Init.DataSize <= SAI_DATASIZE_16) 00791 { 00792 hsai->InterruptServiceRoutine = SAI_Transmit_IT16Bit; 00793 } 00794 else 00795 { 00796 hsai->InterruptServiceRoutine = SAI_Transmit_IT32Bit; 00797 } 00798 00799 /* Enable FRQ and OVRUDR interrupts */ 00800 __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT)); 00801 00802 /* Check if the SAI is already enabled */ 00803 if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET) 00804 { 00805 /* Fill the fifo before starting the communication */ 00806 SAI_FillFifo(hsai); 00807 /* Enable SAI peripheral */ 00808 __HAL_SAI_ENABLE(hsai); 00809 } 00810 00811 error : 00812 /* Process Unlocked */ 00813 __HAL_UNLOCK(hsai); 00814 return errorcode; 00815 } 00816 00817 /** 00818 * @brief Receive an amount of data in non-blocking mode with Interrupt. 00819 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 00820 * the configuration information for SAI module. 00821 * @param pData: Pointer to data buffer 00822 * @param Size: Amount of data to be received 00823 * @retval HAL status 00824 */ 00825 HAL_StatusTypeDef HAL_SAI_Receive_IT(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size) 00826 { 00827 HAL_StatusTypeDef errorcode = HAL_OK; 00828 00829 /* Process Locked */ 00830 __HAL_LOCK(hsai); 00831 00832 if((pData == NULL) || (Size == 0)) 00833 { 00834 errorcode = HAL_ERROR; 00835 goto error; 00836 } 00837 00838 if(hsai->State != HAL_SAI_STATE_READY) 00839 { 00840 errorcode = HAL_BUSY; 00841 goto error; 00842 } 00843 00844 hsai->pBuffPtr = pData; 00845 hsai->XferSize = Size; 00846 hsai->XferCount = Size; 00847 hsai->ErrorCode = HAL_SAI_ERROR_NONE; 00848 hsai->State = HAL_SAI_STATE_BUSY_RX; 00849 if((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING)) 00850 { 00851 hsai->InterruptServiceRoutine = SAI_Receive_IT8Bit; 00852 } 00853 else if(hsai->Init.DataSize <= SAI_DATASIZE_16) 00854 { 00855 hsai->InterruptServiceRoutine = SAI_Receive_IT16Bit; 00856 } 00857 else 00858 { 00859 hsai->InterruptServiceRoutine = SAI_Receive_IT32Bit; 00860 } 00861 00862 /* Enable the interrupts */ 00863 __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT)); 00864 00865 /* Check if the SAI is already enabled */ 00866 if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET) 00867 { 00868 /* Enable SAI peripheral */ 00869 __HAL_SAI_ENABLE(hsai); 00870 } 00871 00872 error : 00873 /* Process Unlocked */ 00874 __HAL_UNLOCK(hsai); 00875 return errorcode; 00876 } 00877 00878 /** 00879 * @brief Pause the audio stream playing from the Media. 00880 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 00881 * the configuration information for SAI module. 00882 * @retval HAL status 00883 */ 00884 HAL_StatusTypeDef HAL_SAI_DMAPause(SAI_HandleTypeDef *hsai) 00885 { 00886 /* Process Locked */ 00887 __HAL_LOCK(hsai); 00888 00889 /* Pause the audio file playing by disabling the SAI DMA requests */ 00890 hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN; 00891 00892 /* Process Unlocked */ 00893 __HAL_UNLOCK(hsai); 00894 00895 return HAL_OK; 00896 } 00897 00898 /** 00899 * @brief Resume the audio stream playing from the Media. 00900 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 00901 * the configuration information for SAI module. 00902 * @retval HAL status 00903 */ 00904 HAL_StatusTypeDef HAL_SAI_DMAResume(SAI_HandleTypeDef *hsai) 00905 { 00906 /* Process Locked */ 00907 __HAL_LOCK(hsai); 00908 00909 /* Enable the SAI DMA requests */ 00910 hsai->Instance->CR1 |= SAI_xCR1_DMAEN; 00911 00912 /* If the SAI peripheral is still not enabled, enable it */ 00913 if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET) 00914 { 00915 /* Enable SAI peripheral */ 00916 __HAL_SAI_ENABLE(hsai); 00917 } 00918 00919 /* Process Unlocked */ 00920 __HAL_UNLOCK(hsai); 00921 00922 return HAL_OK; 00923 } 00924 00925 /** 00926 * @brief Stop the audio stream playing from the Media. 00927 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 00928 * the configuration information for SAI module. 00929 * @retval HAL status 00930 */ 00931 HAL_StatusTypeDef HAL_SAI_DMAStop(SAI_HandleTypeDef *hsai) 00932 { 00933 /* Process Locked */ 00934 __HAL_LOCK(hsai); 00935 00936 /* Disable the SAI DMA request */ 00937 hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN; 00938 00939 /* Abort the SAI DMA Channel */ 00940 if(hsai->hdmatx != NULL) 00941 { 00942 HAL_DMA_Abort(hsai->hdmatx); 00943 } 00944 00945 if(hsai->hdmarx != NULL) 00946 { 00947 HAL_DMA_Abort(hsai->hdmarx); 00948 } 00949 00950 /* Disable SAI peripheral */ 00951 SAI_Disable(hsai); 00952 00953 hsai->State = HAL_SAI_STATE_READY; 00954 00955 /* Process Unlocked */ 00956 __HAL_UNLOCK(hsai); 00957 00958 return HAL_OK; 00959 } 00960 00961 /** 00962 * @brief Abort the current transfer and disable the SAI. 00963 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 00964 * the configuration information for SAI module. 00965 * @retval HAL status 00966 */ 00967 HAL_StatusTypeDef HAL_SAI_Abort(SAI_HandleTypeDef *hsai) 00968 { 00969 /* Disable the SAI DMA request */ 00970 hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN; 00971 00972 /* Abort the SAI DMA Channel */ 00973 if(hsai->hdmatx != NULL) 00974 { 00975 HAL_DMA_Abort(hsai->hdmatx); 00976 } 00977 00978 if(hsai->hdmarx != NULL) 00979 { 00980 HAL_DMA_Abort(hsai->hdmarx); 00981 } 00982 00983 /* Disabled All interrupt and clear all the flag */ 00984 hsai->Instance->IMR = 0; 00985 hsai->Instance->CLRFR = 0xFFFFFFFF; 00986 00987 /* Disable SAI peripheral */ 00988 SAI_Disable(hsai); 00989 00990 /* Flush the fifo */ 00991 SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH); 00992 00993 hsai->State = HAL_SAI_STATE_READY; 00994 00995 /* Process Unlocked */ 00996 __HAL_UNLOCK(hsai); 00997 00998 return HAL_OK; 00999 } 01000 01001 /** 01002 * @brief Transmit an amount of data in non-blocking mode with DMA. 01003 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01004 * the configuration information for SAI module. 01005 * @param pData: Pointer to data buffer 01006 * @param Size: Amount of data to be sent 01007 * @retval HAL status 01008 */ 01009 HAL_StatusTypeDef HAL_SAI_Transmit_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size) 01010 { 01011 HAL_StatusTypeDef errorcode = HAL_OK; 01012 01013 /* Process Locked */ 01014 __HAL_LOCK(hsai); 01015 01016 if((pData == NULL) || (Size == 0)) 01017 { 01018 errorcode = HAL_ERROR; 01019 goto error; 01020 } 01021 01022 if(hsai->State != HAL_SAI_STATE_READY) 01023 { 01024 errorcode = HAL_BUSY; 01025 goto error; 01026 } 01027 01028 hsai->pBuffPtr = pData; 01029 hsai->XferSize = Size; 01030 hsai->XferCount = Size; 01031 hsai->ErrorCode = HAL_SAI_ERROR_NONE; 01032 hsai->State = HAL_SAI_STATE_BUSY_TX; 01033 01034 /* Set the SAI Tx DMA Half transfer complete callback */ 01035 hsai->hdmatx->XferHalfCpltCallback = SAI_DMATxHalfCplt; 01036 01037 /* Set the SAI TxDMA transfer complete callback */ 01038 hsai->hdmatx->XferCpltCallback = SAI_DMATxCplt; 01039 01040 /* Set the DMA error callback */ 01041 hsai->hdmatx->XferErrorCallback = SAI_DMAError; 01042 01043 /* Enable the Tx DMA Channel */ 01044 HAL_DMA_Start_IT(hsai->hdmatx, (uint32_t)hsai->pBuffPtr, (uint32_t)&hsai->Instance->DR, hsai->XferSize); 01045 01046 /* Check if the SAI is already enabled */ 01047 if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET) 01048 { 01049 /* Enable SAI peripheral */ 01050 __HAL_SAI_ENABLE(hsai); 01051 } 01052 01053 /* Enable the interrupts for error handling */ 01054 __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA)); 01055 01056 /* Enable SAI Tx DMA Request */ 01057 hsai->Instance->CR1 |= SAI_xCR1_DMAEN; 01058 01059 error : 01060 /* Process Unlocked */ 01061 __HAL_UNLOCK(hsai); 01062 return errorcode; 01063 } 01064 01065 /** 01066 * @brief Receive an amount of data in non-blocking mode with DMA. 01067 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01068 * the configuration information for SAI module. 01069 * @param pData: Pointer to data buffer 01070 * @param Size: Amount of data to be received 01071 * @retval HAL status 01072 */ 01073 HAL_StatusTypeDef HAL_SAI_Receive_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size) 01074 { 01075 HAL_StatusTypeDef errorcode = HAL_OK; 01076 01077 /* Process Locked */ 01078 __HAL_LOCK(hsai); 01079 01080 if((pData == NULL) || (Size == 0)) 01081 { 01082 errorcode = HAL_ERROR; 01083 goto error; 01084 } 01085 01086 if(hsai->State != HAL_SAI_STATE_READY) 01087 { 01088 errorcode = HAL_BUSY; 01089 goto error; 01090 } 01091 hsai->pBuffPtr = pData; 01092 hsai->XferSize = Size; 01093 hsai->XferCount = Size; 01094 hsai->ErrorCode = HAL_SAI_ERROR_NONE; 01095 hsai->State = HAL_SAI_STATE_BUSY_RX; 01096 01097 /* Set the SAI Rx DMA Half transfer complete callback */ 01098 hsai->hdmarx->XferHalfCpltCallback = SAI_DMARxHalfCplt; 01099 01100 /* Set the SAI Rx DMA transfer complete callback */ 01101 hsai->hdmarx->XferCpltCallback = SAI_DMARxCplt; 01102 01103 /* Set the DMA error callback */ 01104 hsai->hdmarx->XferErrorCallback = SAI_DMAError; 01105 01106 /* Enable the Rx DMA Channel */ 01107 HAL_DMA_Start_IT(hsai->hdmarx, (uint32_t)&hsai->Instance->DR, (uint32_t)hsai->pBuffPtr, hsai->XferSize); 01108 01109 /* Check if the SAI is already enabled */ 01110 if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET) 01111 { 01112 /* Enable SAI peripheral */ 01113 __HAL_SAI_ENABLE(hsai); 01114 } 01115 01116 /* Enable the interrupts for error handling */ 01117 __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA)); 01118 01119 /* Enable SAI Rx DMA Request */ 01120 hsai->Instance->CR1 |= SAI_xCR1_DMAEN; 01121 01122 error : 01123 /* Process Unlocked */ 01124 __HAL_UNLOCK(hsai); 01125 return errorcode; 01126 } 01127 01128 /** 01129 * @brief Enable the Tx mute mode. 01130 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01131 * the configuration information for SAI module. 01132 * @param val: value sent during the mute @ref SAI_Block_Mute_Value 01133 * @retval HAL status 01134 */ 01135 HAL_StatusTypeDef HAL_SAI_EnableTxMuteMode(SAI_HandleTypeDef *hsai, uint16_t val) 01136 { 01137 assert_param(IS_SAI_BLOCK_MUTE_VALUE(val)); 01138 01139 if(hsai->State != HAL_SAI_STATE_RESET) 01140 { 01141 CLEAR_BIT(hsai->Instance->CR2, SAI_xCR2_MUTEVAL | SAI_xCR2_MUTE); 01142 SET_BIT(hsai->Instance->CR2, SAI_xCR2_MUTE | val); 01143 return HAL_OK; 01144 } 01145 return HAL_ERROR; 01146 } 01147 01148 /** 01149 * @brief Disable the Tx mute mode. 01150 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01151 * the configuration information for SAI module. 01152 * @retval HAL status 01153 */ 01154 HAL_StatusTypeDef HAL_SAI_DisableTxMuteMode(SAI_HandleTypeDef *hsai) 01155 { 01156 if(hsai->State != HAL_SAI_STATE_RESET) 01157 { 01158 CLEAR_BIT(hsai->Instance->CR2, SAI_xCR2_MUTEVAL | SAI_xCR2_MUTE); 01159 return HAL_OK; 01160 } 01161 return HAL_ERROR; 01162 } 01163 01164 /** 01165 * @brief Enable the Rx mute detection. 01166 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01167 * the configuration information for SAI module. 01168 * @param callback: function called when the mute is detected 01169 * @param counter: number a data before mute detection max 63. 01170 * @retval HAL status 01171 */ 01172 HAL_StatusTypeDef HAL_SAI_EnableRxMuteMode(SAI_HandleTypeDef *hsai, SAIcallback callback, uint16_t counter) 01173 { 01174 assert_param(IS_SAI_BLOCK_MUTE_COUNTER(counter)); 01175 01176 if(hsai->State != HAL_SAI_STATE_RESET) 01177 { 01178 /* set the mute counter */ 01179 CLEAR_BIT(hsai->Instance->CR2, SAI_xCR2_MUTECNT); 01180 SET_BIT(hsai->Instance->CR2, ((uint32_t)counter << 6)); 01181 hsai->mutecallback = callback; 01182 /* enable the IT interrupt */ 01183 __HAL_SAI_ENABLE_IT(hsai, SAI_IT_MUTEDET); 01184 return HAL_OK; 01185 } 01186 return HAL_ERROR; 01187 } 01188 01189 /** 01190 * @brief Disable the Rx mute detection. 01191 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01192 * the configuration information for SAI module. 01193 * @retval HAL status 01194 */ 01195 HAL_StatusTypeDef HAL_SAI_DisableRxMuteMode(SAI_HandleTypeDef *hsai) 01196 { 01197 if(hsai->State != HAL_SAI_STATE_RESET) 01198 { 01199 /* set the mutecallback to NULL */ 01200 hsai->mutecallback = (SAIcallback)NULL; 01201 /* enable the IT interrupt */ 01202 __HAL_SAI_DISABLE_IT(hsai, SAI_IT_MUTEDET); 01203 return HAL_OK; 01204 } 01205 return HAL_ERROR; 01206 } 01207 01208 /** 01209 * @brief Handle SAI interrupt request. 01210 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01211 * the configuration information for SAI module. 01212 * @retval None 01213 */ 01214 void HAL_SAI_IRQHandler(SAI_HandleTypeDef *hsai) 01215 { 01216 if(hsai->State != HAL_SAI_STATE_RESET) 01217 { 01218 __IO uint32_t tmpFlag = hsai->Instance->SR; 01219 __IO uint32_t tmpItSource = hsai->Instance->IMR; 01220 01221 if(((tmpFlag & SAI_xSR_FREQ) == SAI_xSR_FREQ) && ((tmpItSource & SAI_IT_FREQ) == SAI_IT_FREQ)) 01222 { 01223 hsai->InterruptServiceRoutine(hsai); 01224 goto exit; 01225 } 01226 01227 /* check the flag only if one of them is set */ 01228 if(tmpFlag != 0x00000000) 01229 { 01230 /* SAI Overrun error interrupt occurred ----------------------------------*/ 01231 if(((tmpFlag & SAI_FLAG_OVRUDR) == SAI_FLAG_OVRUDR) && ((tmpItSource & SAI_IT_OVRUDR) == SAI_IT_OVRUDR)) 01232 { 01233 /* Clear the SAI Overrun flag */ 01234 __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR); 01235 /* Change the SAI error code */ 01236 hsai->ErrorCode = ((hsai->State == HAL_SAI_STATE_BUSY_RX) ? HAL_SAI_ERROR_OVR : HAL_SAI_ERROR_UDR); 01237 /* the transfer is not stopped, we will forward the information to the user and we let the user decide what needs to be done */ 01238 HAL_SAI_ErrorCallback(hsai); 01239 goto exit; 01240 } 01241 01242 /* SAI mutedet interrupt occurred ----------------------------------*/ 01243 if(((tmpFlag & SAI_FLAG_MUTEDET) == SAI_FLAG_MUTEDET) && ((tmpItSource & SAI_IT_MUTEDET) == SAI_IT_MUTEDET)) 01244 { 01245 /* Clear the SAI mutedet flag */ 01246 __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_MUTEDET); 01247 /* call the call back function */ 01248 if(hsai->mutecallback != (SAIcallback)NULL) 01249 { 01250 /* inform the user that an RX mute event has been detected */ 01251 hsai->mutecallback(); 01252 } 01253 goto exit; 01254 } 01255 01256 /* SAI AFSDET interrupt occurred ----------------------------------*/ 01257 if(((tmpFlag & SAI_FLAG_AFSDET) == SAI_FLAG_AFSDET) && ((tmpItSource & SAI_IT_AFSDET) == SAI_IT_AFSDET)) 01258 { 01259 /* Change the SAI error code */ 01260 hsai->ErrorCode = HAL_SAI_ERROR_AFSDET; 01261 goto error; 01262 } 01263 01264 /* SAI LFSDET interrupt occurred ----------------------------------*/ 01265 if(((tmpFlag & SAI_FLAG_LFSDET) == SAI_FLAG_LFSDET) && ((tmpItSource & SAI_IT_LFSDET) == SAI_IT_LFSDET)) 01266 { 01267 /* Change the SAI error code */ 01268 hsai->ErrorCode = HAL_SAI_ERROR_LFSDET; 01269 goto error; 01270 } 01271 01272 /* SAI WCKCFG interrupt occurred ----------------------------------*/ 01273 if(((tmpFlag & SAI_FLAG_WCKCFG) == SAI_FLAG_WCKCFG) && ((tmpItSource & SAI_IT_WCKCFG) == SAI_IT_WCKCFG)) 01274 { 01275 /* Change the SAI error code */ 01276 hsai->ErrorCode = HAL_SAI_ERROR_WCKCFG; 01277 goto error; 01278 } 01279 } 01280 } 01281 01282 exit : 01283 return; 01284 error : 01285 /* Abort the current communication, disable the SAI block, and clear all the flags */ 01286 HAL_SAI_Abort(hsai); 01287 HAL_SAI_ErrorCallback(hsai); 01288 return; 01289 } 01290 01291 /** 01292 * @brief Tx Transfer completed callback. 01293 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01294 * the configuration information for SAI module. 01295 * @retval None 01296 */ 01297 __weak void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai) 01298 { 01299 /* NOTE : This function should not be modified, when the callback is needed, 01300 the HAL_SAI_TxCpltCallback could be implemented in the user file 01301 */ 01302 } 01303 01304 /** 01305 * @brief Tx Transfer Half completed callback. 01306 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01307 * the configuration information for SAI module. 01308 * @retval None 01309 */ 01310 __weak void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai) 01311 { 01312 /* NOTE : This function should not be modified, when the callback is needed, 01313 the HAL_SAI_TxHalfCpltCallback could be implemented in the user file 01314 */ 01315 } 01316 01317 /** 01318 * @brief Rx Transfer completed callback. 01319 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01320 * the configuration information for SAI module. 01321 * @retval None 01322 */ 01323 __weak void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai) 01324 { 01325 /* NOTE : This function should not be modified, when the callback is needed, 01326 the HAL_SAI_RxCpltCallback could be implemented in the user file 01327 */ 01328 } 01329 01330 /** 01331 * @brief Rx Transfer half completed callback. 01332 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01333 * the configuration information for SAI module. 01334 * @retval None 01335 */ 01336 __weak void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai) 01337 { 01338 /* NOTE : This function should not be modified, when the callback is needed, 01339 the HAL_SAI_RxCpltCallback could be implemented in the user file 01340 */ 01341 } 01342 01343 /** 01344 * @brief SAI error callback. 01345 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01346 * the configuration information for SAI module. 01347 * @retval None 01348 */ 01349 __weak void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai) 01350 { 01351 /* NOTE : This function should not be modified, when the callback is needed, 01352 the HAL_SAI_ErrorCallback could be implemented in the user file 01353 */ 01354 } 01355 01356 /** 01357 * @} 01358 */ 01359 01360 01361 /** @defgroup SAI_Exported_Functions_Group3 Peripheral State functions 01362 * @brief Peripheral State functions 01363 * 01364 @verbatim 01365 =============================================================================== 01366 ##### Peripheral State and Errors functions ##### 01367 =============================================================================== 01368 [..] 01369 This subsection permits to get in run-time the status of the peripheral 01370 and the data flow. 01371 01372 @endverbatim 01373 * @{ 01374 */ 01375 01376 /** 01377 * @brief Return the SAI handle state. 01378 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01379 * the configuration information for SAI module. 01380 * @retval HAL state 01381 */ 01382 HAL_SAI_StateTypeDef HAL_SAI_GetState(SAI_HandleTypeDef *hsai) 01383 { 01384 /* Return SAI handle state */ 01385 return hsai->State; 01386 } 01387 01388 /** 01389 * @brief Return the SAI error code. 01390 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01391 * the configuration information for the specified SAI Block. 01392 * @retval SAI Error Code 01393 */ 01394 uint32_t HAL_SAI_GetError(SAI_HandleTypeDef *hsai) 01395 { 01396 return hsai->ErrorCode; 01397 } 01398 /** 01399 * @} 01400 */ 01401 01402 /** 01403 * @} 01404 */ 01405 01406 /** @addtogroup SAI_Private_Functions 01407 * @brief Private functions 01408 * @{ 01409 */ 01410 /** 01411 * @brief Initialize the SAI I2S protocol according to the specified parameters 01412 * in the SAI_InitTypeDef and create the associated handle. 01413 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01414 * the configuration information for SAI module. 01415 * @param protocol: one of the supported protocol 01416 * @param datasize: one of the supported datasize @ref SAI_Protocol_DataSize 01417 * the configuration information for SAI module. 01418 * @param nbslot: number of slot minimum value is 2 and max is 16. 01419 * the value must be a multiple of 2. 01420 * @retval HAL status 01421 */ 01422 static HAL_StatusTypeDef SAI_InitI2S(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot) 01423 { 01424 HAL_StatusTypeDef errorcode = HAL_OK; 01425 01426 hsai->Init.Protocol = SAI_FREE_PROTOCOL; 01427 hsai->Init.FirstBit = SAI_FIRSTBIT_MSB; 01428 hsai->Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE; 01429 hsai->FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION; 01430 hsai->SlotInit.SlotActive = SAI_SLOTACTIVE_ALL; 01431 hsai->SlotInit.FirstBitOffset = 0; 01432 hsai->SlotInit.SlotNumber = nbslot; 01433 01434 /* in IS2 the number of slot must be even */ 01435 if((nbslot & 0x1) != 0 ) 01436 { 01437 return HAL_ERROR; 01438 } 01439 01440 switch(protocol) 01441 { 01442 case SAI_I2S_STANDARD : 01443 hsai->FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW; 01444 hsai->FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT; 01445 break; 01446 case SAI_I2S_MSBJUSTIFIED : 01447 case SAI_I2S_LSBJUSTIFIED : 01448 hsai->FrameInit.FSPolarity = SAI_FS_ACTIVE_HIGH; 01449 hsai->FrameInit.FSOffset = SAI_FS_FIRSTBIT; 01450 break; 01451 default : 01452 return HAL_ERROR; 01453 } 01454 01455 /* Frame definition */ 01456 hsai->Init.DataSize = 0xFFFFFFFF; 01457 if(datasize == SAI_PROTOCOL_DATASIZE_16BIT) 01458 { 01459 hsai->Init.DataSize = SAI_DATASIZE_16; 01460 hsai->FrameInit.FrameLength = 32*(nbslot/2); 01461 hsai->FrameInit.ActiveFrameLength = 16*(nbslot/2); 01462 hsai->SlotInit.SlotSize = SAI_SLOTSIZE_16B; 01463 } 01464 else if(datasize == SAI_PROTOCOL_DATASIZE_16BITEXTENDED) 01465 { 01466 if(hsai->Init.DataSize == 0xFFFFFFFF) 01467 { 01468 hsai->Init.DataSize = SAI_DATASIZE_16; 01469 } 01470 } 01471 else if(datasize == SAI_PROTOCOL_DATASIZE_24BIT) 01472 { 01473 if(hsai->Init.DataSize == 0xFFFFFFFF) 01474 { 01475 hsai->Init.DataSize = SAI_DATASIZE_24; 01476 } 01477 } 01478 else if(datasize == SAI_PROTOCOL_DATASIZE_32BIT) 01479 { 01480 if(hsai->Init.DataSize == 0xFFFFFFFF) 01481 { 01482 hsai->Init.DataSize = SAI_DATASIZE_32; 01483 } 01484 } 01485 else 01486 { 01487 errorcode = HAL_ERROR; 01488 } 01489 01490 if(errorcode == HAL_OK) 01491 { 01492 hsai->FrameInit.FrameLength = 64*(nbslot/2); 01493 hsai->FrameInit.ActiveFrameLength = 32*(nbslot/2); 01494 hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B; 01495 01496 if(protocol == SAI_I2S_LSBJUSTIFIED) 01497 { 01498 if (datasize == SAI_PROTOCOL_DATASIZE_16BITEXTENDED) 01499 { 01500 hsai->SlotInit.FirstBitOffset = 16; 01501 } 01502 else if (datasize == SAI_PROTOCOL_DATASIZE_24BIT) 01503 { 01504 hsai->SlotInit.FirstBitOffset = 8; 01505 } 01506 } 01507 } 01508 01509 return errorcode; 01510 } 01511 01512 /** 01513 * @brief Initialize the SAI PCM protocol according to the specified parameters 01514 * in the SAI_InitTypeDef and create the associated handle. 01515 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01516 * the configuration information for SAI module. 01517 * @param protocol: one of the supported protocol 01518 * @param datasize: one of the supported datasize @ref SAI_Protocol_DataSize 01519 * @param nbslot: number of slot minimum value is 1 and the max is 16. 01520 * @retval HAL status 01521 */ 01522 static HAL_StatusTypeDef SAI_InitPCM(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot) 01523 { 01524 hsai->Init.Protocol = SAI_FREE_PROTOCOL; 01525 hsai->Init.FirstBit = SAI_FIRSTBIT_MSB; 01526 hsai->Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE; 01527 hsai->FrameInit.FSDefinition = SAI_FS_STARTFRAME; 01528 hsai->FrameInit.FSPolarity = SAI_FS_ACTIVE_HIGH; 01529 hsai->FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT; 01530 hsai->SlotInit.FirstBitOffset = 0; 01531 hsai->SlotInit.SlotNumber = nbslot; 01532 hsai->SlotInit.SlotActive = SAI_SLOTACTIVE_ALL; 01533 01534 switch(protocol) 01535 { 01536 case SAI_PCM_SHORT : 01537 hsai->FrameInit.ActiveFrameLength = 1; 01538 break; 01539 case SAI_PCM_LONG : 01540 hsai->FrameInit.ActiveFrameLength = 13; 01541 break; 01542 default : 01543 return HAL_ERROR; 01544 } 01545 01546 switch(datasize) 01547 { 01548 case SAI_PROTOCOL_DATASIZE_16BIT: 01549 hsai->Init.DataSize = SAI_DATASIZE_16; 01550 hsai->FrameInit.FrameLength = 16 * nbslot; 01551 hsai->SlotInit.SlotSize = SAI_SLOTSIZE_16B; 01552 break; 01553 case SAI_PROTOCOL_DATASIZE_16BITEXTENDED : 01554 hsai->Init.DataSize = SAI_DATASIZE_16; 01555 hsai->FrameInit.FrameLength = 32 * nbslot; 01556 hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B; 01557 break; 01558 01559 case SAI_PROTOCOL_DATASIZE_32BIT: 01560 hsai->Init.DataSize = SAI_DATASIZE_32; 01561 hsai->FrameInit.FrameLength = 32 * nbslot; 01562 hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B; 01563 break; 01564 default : 01565 return HAL_ERROR; 01566 } 01567 01568 return HAL_OK; 01569 } 01570 01571 /** 01572 * @brief Fill the fifo. 01573 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01574 * the configuration information for SAI module. 01575 * @retval None 01576 */ 01577 static void SAI_FillFifo(SAI_HandleTypeDef *hsai) 01578 { 01579 /* fill the fifo with data before to enabled the SAI */ 01580 while((hsai->Instance->SR & SAI_xSR_FLVL) != SAI_FIFOSTATUS_FULL) 01581 { 01582 if((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING)) 01583 { 01584 hsai->Instance->DR = (*hsai->pBuffPtr++); 01585 } 01586 else if(hsai->Init.DataSize <= SAI_DATASIZE_16) 01587 { 01588 hsai->Instance->DR = *((uint32_t *)hsai->pBuffPtr); 01589 hsai->pBuffPtr+= 2; 01590 } 01591 else 01592 { 01593 hsai->Instance->DR = *((uint32_t *)hsai->pBuffPtr); 01594 hsai->pBuffPtr+= 4; 01595 } 01596 hsai->XferCount--; 01597 } 01598 } 01599 01600 /** 01601 * @brief Return the interrupt flag to set according the SAI setup. 01602 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01603 * the configuration information for SAI module. 01604 * @param mode: SAI_MODE_DMA or SAI_MODE_IT 01605 * @retval the list of the IT flag to enable 01606 */ 01607 static int32_t SAI_InterruptFlag(SAI_HandleTypeDef *hsai, uint32_t mode) 01608 { 01609 int32_t tmpIT = SAI_IT_OVRUDR; 01610 01611 if(mode == SAI_MODE_IT) 01612 { 01613 tmpIT|= SAI_IT_FREQ; 01614 } 01615 01616 if((hsai->Init.AudioMode == SAI_MODESLAVE_RX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX)) 01617 { 01618 tmpIT|= SAI_IT_AFSDET | SAI_IT_LFSDET; 01619 } 01620 else 01621 { 01622 /* hsai has been configured in master mode */ 01623 tmpIT|= SAI_IT_WCKCFG; 01624 } 01625 return tmpIT; 01626 } 01627 01628 /** 01629 * @brief Disable the SAI and wait for the disabling. 01630 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01631 * the configuration information for SAI module. 01632 * @retval None 01633 */ 01634 static HAL_StatusTypeDef SAI_Disable(SAI_HandleTypeDef *hsai) 01635 { 01636 uint32_t tickstart = HAL_GetTick(); 01637 HAL_StatusTypeDef errorcode = HAL_OK; 01638 01639 __HAL_SAI_DISABLE(hsai); 01640 while((hsai->Instance->CR1 & SAI_xCR1_SAIEN) != RESET) 01641 { 01642 /* Check for the Timeout */ 01643 if((HAL_GetTick() - tickstart) > SAI_DEFAULT_TIMEOUT) 01644 { 01645 errorcode = HAL_TIMEOUT; 01646 goto error; 01647 } 01648 } 01649 error: 01650 return errorcode; 01651 } 01652 01653 /** 01654 * @brief Tx Handler for Transmit in Interrupt mode 8-bit transfer. 01655 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01656 * the configuration information for SAI module. 01657 * @retval None 01658 */ 01659 static void SAI_Transmit_IT8Bit(SAI_HandleTypeDef *hsai) 01660 { 01661 /* Write data on DR register */ 01662 hsai->Instance->DR = (*hsai->pBuffPtr++); 01663 hsai->XferCount--; 01664 01665 /* Handle the end of the transmission */ 01666 if(hsai->XferCount == 0) 01667 { 01668 /* Disable FREQ and OVRUDR interrupts */ 01669 __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT)); 01670 hsai->State = HAL_SAI_STATE_READY; 01671 HAL_SAI_TxCpltCallback(hsai); 01672 } 01673 } 01674 01675 /** 01676 * @brief Tx Handler for Transmit in Interrupt mode for 16-bit transfer. 01677 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01678 * the configuration information for SAI module. 01679 * @retval None 01680 */ 01681 static void SAI_Transmit_IT16Bit(SAI_HandleTypeDef *hsai) 01682 { 01683 /* Write data on DR register */ 01684 hsai->Instance->DR = *(uint16_t *)hsai->pBuffPtr; 01685 hsai->pBuffPtr+=2; 01686 hsai->XferCount--; 01687 01688 /* Handle the end of the transmission */ 01689 if(hsai->XferCount == 0) 01690 { 01691 /* Disable FREQ and OVRUDR interrupts */ 01692 __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT)); 01693 hsai->State = HAL_SAI_STATE_READY; 01694 HAL_SAI_TxCpltCallback(hsai); 01695 } 01696 } 01697 01698 /** 01699 * @brief Tx Handler for Transmit in Interrupt mode for 32-bit transfer. 01700 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01701 * the configuration information for SAI module. 01702 * @retval None 01703 */ 01704 static void SAI_Transmit_IT32Bit(SAI_HandleTypeDef *hsai) 01705 { 01706 /* Write data on DR register */ 01707 hsai->Instance->DR = *(uint32_t *)hsai->pBuffPtr; 01708 hsai->pBuffPtr+=4; 01709 hsai->XferCount--; 01710 01711 /* Handle the end of the transmission */ 01712 if(hsai->XferCount == 0) 01713 { 01714 /* Disable FREQ and OVRUDR interrupts */ 01715 __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT)); 01716 hsai->State = HAL_SAI_STATE_READY; 01717 HAL_SAI_TxCpltCallback(hsai); 01718 } 01719 } 01720 01721 /** 01722 * @brief Rx Handler for Receive in Interrupt mode 8-bit transfer. 01723 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01724 * the configuration information for SAI module. 01725 * @retval None 01726 */ 01727 static void SAI_Receive_IT8Bit(SAI_HandleTypeDef *hsai) 01728 { 01729 /* Receive data */ 01730 (*hsai->pBuffPtr++) = hsai->Instance->DR; 01731 hsai->XferCount--; 01732 01733 /* Check end of the transfer */ 01734 if(hsai->XferCount == 0) 01735 { 01736 /* Disable TXE and OVRUDR interrupts */ 01737 __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT)); 01738 01739 /* Clear the SAI Overrun flag */ 01740 __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR); 01741 01742 hsai->State = HAL_SAI_STATE_READY; 01743 HAL_SAI_RxCpltCallback(hsai); 01744 } 01745 } 01746 01747 /** 01748 * @brief Rx Handler for Receive in Interrupt mode for 16-bit transfer. 01749 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01750 * the configuration information for SAI module. 01751 * @retval None 01752 */ 01753 static void SAI_Receive_IT16Bit(SAI_HandleTypeDef *hsai) 01754 { 01755 /* Receive data */ 01756 *(uint16_t*)hsai->pBuffPtr = hsai->Instance->DR; 01757 hsai->pBuffPtr+=2; 01758 hsai->XferCount--; 01759 01760 /* Check end of the transfer */ 01761 if(hsai->XferCount == 0) 01762 { 01763 /* Disable TXE and OVRUDR interrupts */ 01764 __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT)); 01765 01766 /* Clear the SAI Overrun flag */ 01767 __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR); 01768 01769 hsai->State = HAL_SAI_STATE_READY; 01770 HAL_SAI_RxCpltCallback(hsai); 01771 } 01772 } 01773 /** 01774 * @brief Rx Handler for Receive in Interrupt mode for 32-bit transfer. 01775 * @param hsai: pointer to a SAI_HandleTypeDef structure that contains 01776 * the configuration information for SAI module. 01777 * @retval None 01778 */ 01779 static void SAI_Receive_IT32Bit(SAI_HandleTypeDef *hsai) 01780 { 01781 /* Receive data */ 01782 *(uint32_t*)hsai->pBuffPtr = hsai->Instance->DR; 01783 hsai->pBuffPtr+=4; 01784 hsai->XferCount--; 01785 01786 /* Check end of the transfer */ 01787 if(hsai->XferCount == 0) 01788 { 01789 /* Disable TXE and OVRUDR interrupts */ 01790 __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT)); 01791 01792 /* Clear the SAI Overrun flag */ 01793 __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR); 01794 01795 hsai->State = HAL_SAI_STATE_READY; 01796 HAL_SAI_RxCpltCallback(hsai); 01797 } 01798 } 01799 /** 01800 * @brief DMA SAI transmit process complete callback. 01801 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 01802 * the configuration information for the specified DMA module. 01803 * @retval None 01804 */ 01805 static void SAI_DMATxCplt(DMA_HandleTypeDef *hdma) 01806 { 01807 SAI_HandleTypeDef* hsai = (SAI_HandleTypeDef*)((DMA_HandleTypeDef* )hdma)->Parent; 01808 01809 if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0) 01810 { 01811 hsai->XferCount = 0; 01812 01813 /* Disable SAI Tx DMA Request */ 01814 hsai->Instance->CR1 &= (uint32_t)(~SAI_xCR1_DMAEN); 01815 01816 /* Stop the interrupts error handling */ 01817 __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA)); 01818 01819 hsai->State= HAL_SAI_STATE_READY; 01820 } 01821 HAL_SAI_TxCpltCallback(hsai); 01822 } 01823 01824 /** 01825 * @brief DMA SAI transmit process half complete callback. 01826 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 01827 * the configuration information for the specified DMA module. 01828 * @retval None 01829 */ 01830 static void SAI_DMATxHalfCplt(DMA_HandleTypeDef *hdma) 01831 { 01832 SAI_HandleTypeDef* hsai = (SAI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; 01833 01834 HAL_SAI_TxHalfCpltCallback(hsai); 01835 } 01836 01837 /** 01838 * @brief DMA SAI receive process complete callback. 01839 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 01840 * the configuration information for the specified DMA module. 01841 * @retval None 01842 */ 01843 static void SAI_DMARxCplt(DMA_HandleTypeDef *hdma) 01844 { 01845 SAI_HandleTypeDef* hsai = ( SAI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 01846 if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0) 01847 { 01848 /* Disable Rx DMA Request */ 01849 hsai->Instance->CR1 &= (uint32_t)(~SAI_xCR1_DMAEN); 01850 hsai->XferCount = 0; 01851 01852 /* Stop the interrupts error handling */ 01853 __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA)); 01854 01855 hsai->State = HAL_SAI_STATE_READY; 01856 } 01857 HAL_SAI_RxCpltCallback(hsai); 01858 } 01859 01860 /** 01861 * @brief DMA SAI receive process half complete callback. 01862 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 01863 * the configuration information for the specified DMA module. 01864 * @retval None 01865 */ 01866 static void SAI_DMARxHalfCplt(DMA_HandleTypeDef *hdma) 01867 { 01868 SAI_HandleTypeDef* hsai = (SAI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; 01869 01870 HAL_SAI_RxHalfCpltCallback(hsai); 01871 } 01872 /** 01873 * @brief DMA SAI communication error callback. 01874 * @param hdma: pointer to a DMA_HandleTypeDef structure that contains 01875 * the configuration information for the specified DMA module. 01876 * @retval None 01877 */ 01878 static void SAI_DMAError(DMA_HandleTypeDef *hdma) 01879 { 01880 SAI_HandleTypeDef* hsai = ( SAI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; 01881 01882 /* Stop the DMA transfer */ 01883 HAL_SAI_DMAStop(hsai); 01884 01885 /* Set the SAI state ready to be able to start again the process */ 01886 hsai->State= HAL_SAI_STATE_READY; 01887 HAL_SAI_ErrorCallback(hsai); 01888 hsai->XferCount = 0; 01889 } 01890 01891 /** 01892 * @} 01893 */ 01894 01895 #endif /* HAL_SAI_MODULE_ENABLED */ 01896 /** 01897 * @} 01898 */ 01899 01900 /** 01901 * @} 01902 */ 01903 01904 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 01905
Generated on Tue Jul 12 2022 10:58:10 by 1.7.2