STM32H735xx HAL User Manual
stm32h7xx_hal_i2s.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32h7xx_hal_i2s.c
00004   * @author  MCD Application Team
00005   * @brief   I2S HAL module driver.
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities of the Integrated Interchip Sound (I2S) peripheral:
00008   *           + Initialization and de-initialization functions
00009   *           + IO operation functions
00010   *           + Peripheral State and Errors functions
00011   ******************************************************************************
00012   * @attention
00013   *
00014   * Copyright (c) 2017 STMicroelectronics.
00015   * All rights reserved.
00016   *
00017   * This software is licensed under terms that can be found in the LICENSE file
00018   * in the root directory of this software component.
00019   * If no LICENSE file comes with this software, it is provided AS-IS.
00020   *
00021   ******************************************************************************
00022   @verbatim
00023  ===============================================================================
00024                   ##### How to use this driver #####
00025  ===============================================================================
00026  [..]
00027     The I2S HAL driver can be used as follow:
00028 
00029     (#) Declare a I2S_HandleTypeDef handle structure.
00030     (#) Initialize the I2S low level resources by implement the HAL_I2S_MspInit() API:
00031         (##) Enable the SPIx interface clock.
00032         (##) I2S pins configuration:
00033             (+++) Enable the clock for the I2S GPIOs.
00034             (+++) Configure these I2S pins as alternate function pull-up.
00035         (##) NVIC configuration if you need to use interrupt process (HAL_I2S_Transmit_IT()
00036              and HAL_I2S_Receive_IT() APIs).
00037             (+++) Configure the I2Sx interrupt priority.
00038             (+++) Enable the NVIC I2S IRQ handle.
00039         (##) DMA Configuration if you need to use DMA process (HAL_I2S_Transmit_DMA()
00040              and HAL_I2S_Receive_DMA() APIs:
00041             (+++) Declare a DMA handle structure for the Tx/Rx Stream/Channel.
00042             (+++) Enable the DMAx interface clock.
00043             (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
00044             (+++) Configure the DMA Tx/Rx Stream/Channel.
00045             (+++) Associate the initialized DMA handle to the I2S DMA Tx/Rx handle.
00046             (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the
00047                   DMA Tx/Rx Stream/Channel.
00048 
00049    (#) Program the Mode, Standard, Data Format, MCLK Output, Audio frequency and Polarity
00050        using HAL_I2S_Init() function.
00051 
00052    -@- The specific I2S interrupts (Transmission complete interrupt,
00053        RXNE interrupt and Error Interrupts) will be managed using the macros
00054        __HAL_I2S_ENABLE_IT() and __HAL_I2S_DISABLE_IT() inside the transmit and receive process.
00055 
00056         (+@) External clock source is configured after setting correctly
00057              the define constant EXTERNAL_CLOCK_VALUE in the stm32h7xx_hal_conf.h file.
00058 
00059     (#) Three mode of operations are available within this driver :
00060 
00061    *** Polling mode IO operation ***
00062    =================================
00063    [..]
00064      (+) Send an amount of data in blocking mode using HAL_I2S_Transmit()
00065      (+) Receive an amount of data in blocking mode using HAL_I2S_Receive()
00066 
00067    *** Interrupt mode IO operation ***
00068    ===================================
00069    [..]
00070      (+) Send an amount of data in non blocking mode using HAL_I2S_Transmit_IT()
00071      (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
00072          add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
00073      (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
00074          add his own code by customization of function pointer HAL_I2S_TxCpltCallback
00075      (+) Receive an amount of data in non blocking mode using HAL_I2S_Receive_IT()
00076      (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
00077          add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
00078      (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
00079          add his own code by customization of function pointer HAL_I2S_RxCpltCallback
00080      (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
00081          add his own code by customization of function pointer HAL_I2S_ErrorCallback
00082 
00083    *** DMA mode IO operation ***
00084    ==============================
00085    [..]
00086      (+) Send an amount of data in non blocking mode (DMA) using HAL_I2S_Transmit_DMA()
00087      (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
00088          add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
00089      (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
00090          add his own code by customization of function pointer HAL_I2S_TxCpltCallback
00091      (+) Receive an amount of data in non blocking mode (DMA) using HAL_I2S_Receive_DMA()
00092      (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
00093          add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
00094      (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
00095          add his own code by customization of function pointer HAL_I2S_RxCpltCallback
00096      (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
00097          add his own code by customization of function pointer HAL_I2S_ErrorCallback
00098      (+) Pause the DMA Transfer using HAL_I2S_DMAPause()
00099      (+) Resume the DMA Transfer using HAL_I2S_DMAResume()
00100      (+) Stop the DMA Transfer using HAL_I2S_DMAStop()
00101 
00102    *** I2S HAL driver macros list ***
00103    ===================================
00104    [..]
00105      Below the list of most used macros in I2S HAL driver.
00106 
00107       (+) __HAL_I2S_ENABLE: Enable the specified SPI peripheral (in I2S mode)
00108       (+) __HAL_I2S_DISABLE: Disable the specified SPI peripheral (in I2S mode)
00109       (+) __HAL_I2S_ENABLE_IT : Enable the specified I2S interrupts
00110       (+) __HAL_I2S_DISABLE_IT : Disable the specified I2S interrupts
00111       (+) __HAL_I2S_GET_FLAG: Check whether the specified I2S flag is set or not
00112 
00113     [..]
00114       (@) You can refer to the I2S HAL driver header file for more useful macros
00115 
00116    *** I2S HAL driver macros list ***
00117    ===================================
00118    [..]
00119        Callback registration:
00120 
00121       (#) The compilation flag USE_HAL_I2S_REGISTER_CALLBACKS when set to 1UL
00122           allows the user to configure dynamically the driver callbacks.
00123           Use Functions HAL_I2S_RegisterCallback() to register an interrupt callback.
00124 
00125           Function HAL_I2S_RegisterCallback() allows to register following callbacks:
00126             (+) TxCpltCallback        : I2S Tx Completed callback
00127             (+) RxCpltCallback        : I2S Rx Completed callback
00128             (+) TxRxCpltCallback      : I2S TxRx Completed callback
00129             (+) TxHalfCpltCallback    : I2S Tx Half Completed callback
00130             (+) RxHalfCpltCallback    : I2S Rx Half Completed callback
00131             (+) TxRxHalfCpltCallback  : I2S TxRx Half Completed callback
00132             (+) ErrorCallback         : I2S Error callback
00133             (+) MspInitCallback       : I2S Msp Init callback
00134             (+) MspDeInitCallback     : I2S Msp DeInit callback
00135           This function takes as parameters the HAL peripheral handle, the Callback ID
00136           and a pointer to the user callback function.
00137 
00138 
00139       (#) Use function HAL_I2S_UnRegisterCallback to reset a callback to the default
00140           weak function.
00141           HAL_I2S_UnRegisterCallback takes as parameters the HAL peripheral handle,
00142           and the Callback ID.
00143           This function allows to reset following callbacks:
00144             (+) TxCpltCallback        : I2S Tx Completed callback
00145             (+) RxCpltCallback        : I2S Rx Completed callback
00146             (+) TxRxCpltCallback      : I2S TxRx Completed callback
00147             (+) TxHalfCpltCallback    : I2S Tx Half Completed callback
00148             (+) RxHalfCpltCallback    : I2S Rx Half Completed callback
00149             (+) TxRxHalfCpltCallback  : I2S TxRx Half Completed callback
00150             (+) ErrorCallback         : I2S Error callback
00151             (+) MspInitCallback       : I2S Msp Init callback
00152             (+) MspDeInitCallback     : I2S Msp DeInit callback
00153 
00154        By default, after the HAL_I2S_Init() and when the state is HAL_I2S_STATE_RESET
00155        all callbacks are set to the corresponding weak functions:
00156        examples HAL_I2S_MasterTxCpltCallback(), HAL_I2S_MasterRxCpltCallback().
00157        Exception done for MspInit and MspDeInit functions that are
00158        reset to the legacy weak functions in the HAL_I2S_Init()/ HAL_I2S_DeInit() only when
00159        these callbacks are null (not registered beforehand).
00160        If MspInit or MspDeInit are not null, the HAL_I2S_Init()/ HAL_I2S_DeInit()
00161        keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
00162 
00163        Callbacks can be registered/unregistered in HAL_I2S_STATE_READY state only.
00164        Exception done MspInit/MspDeInit functions that can be registered/unregistered
00165        in HAL_I2S_STATE_READY or HAL_I2S_STATE_RESET state,
00166        thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
00167        Then, the user first registers the MspInit/MspDeInit user callbacks
00168        using HAL_I2S_RegisterCallback() before calling HAL_I2S_DeInit()
00169        or HAL_I2S_Init() function.
00170 
00171        When The compilation define USE_HAL_I2S_REGISTER_CALLBACKS is set to 0 or
00172        not defined, the callback registering feature is not available
00173        and weak (surcharged) callbacks are used.
00174 
00175 
00176   @endverbatim
00177   */
00178 
00179 /* Includes ------------------------------------------------------------------*/
00180 #include "stm32h7xx_hal.h"
00181 
00182 #ifdef HAL_I2S_MODULE_ENABLED
00183 
00184 /** @addtogroup STM32H7xx_HAL_Driver
00185   * @{
00186   */
00187 
00188 /** @defgroup I2S I2S
00189   * @brief I2S HAL module driver
00190   * @{
00191   */
00192 
00193 /* Private typedef -----------------------------------------------------------*/
00194 /* Private define ------------------------------------------------------------*/
00195 #define I2S_TIMEOUT 0xFFFFUL
00196 
00197 /* Private macro -------------------------------------------------------------*/
00198 /* Private variables ---------------------------------------------------------*/
00199 /* Private function prototypes -----------------------------------------------*/
00200 /** @defgroup I2S_Private_Functions I2S Private Functions
00201   * @{
00202   */
00203 static void               I2S_DMATxCplt(DMA_HandleTypeDef *hdma);
00204 static void               I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
00205 static void               I2S_DMARxCplt(DMA_HandleTypeDef *hdma);
00206 static void               I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
00207 static void               I2SEx_DMATxRxCplt(DMA_HandleTypeDef *hdma);
00208 static void               I2SEx_DMATxRxHalfCplt(DMA_HandleTypeDef *hdma);
00209 static void               I2S_DMAError(DMA_HandleTypeDef *hdma);
00210 static void               I2S_Transmit_16Bit_IT(I2S_HandleTypeDef *hi2s);
00211 static void               I2S_Transmit_32Bit_IT(I2S_HandleTypeDef *hi2s);
00212 static void               I2S_Receive_16Bit_IT(I2S_HandleTypeDef *hi2s);
00213 static void               I2S_Receive_32Bit_IT(I2S_HandleTypeDef *hi2s);
00214 static HAL_StatusTypeDef  I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State,
00215                                                         uint32_t Timeout);
00216 /**
00217   * @}
00218   */
00219 
00220 /* Exported functions ---------------------------------------------------------*/
00221 
00222 /** @defgroup I2S_Exported_Functions I2S Exported Functions
00223   * @{
00224   */
00225 
00226 /** @defgroup  I2S_Exported_Functions_Group1 Initialization and de-initialization functions
00227   *  @brief    Initialization and Configuration functions
00228   *
00229 @verbatim
00230  ===============================================================================
00231               ##### Initialization and de-initialization functions #####
00232  ===============================================================================
00233     [..]  This subsection provides a set of functions allowing to initialize and
00234           de-initialize the I2Sx peripheral in simplex mode:
00235 
00236       (+) User must Implement HAL_I2S_MspInit() function in which he configures
00237           all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
00238 
00239       (+) Call the function HAL_I2S_Init() to configure the selected device with
00240           the selected configuration:
00241         (++) Mode
00242         (++) Standard
00243         (++) Data Format
00244         (++) MCLK Output
00245         (++) Audio frequency
00246         (++) Polarity
00247 
00248      (+) Call the function HAL_I2S_DeInit() to restore the default configuration
00249           of the selected I2Sx peripheral.
00250   @endverbatim
00251   * @{
00252   */
00253 
00254 /**
00255   * @brief  Initializes the I2S according to the specified parameters
00256   *         in the I2S_InitTypeDef and create the associated handle.
00257   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
00258   *         the configuration information for I2S module
00259   * @retval HAL status
00260   */
00261 HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s)
00262 {
00263   uint32_t i2sdiv;
00264   uint32_t i2sodd;
00265   uint32_t packetlength;
00266   uint32_t tmp;
00267   uint32_t i2sclk;
00268   uint32_t ispcm;
00269 
00270   /* Check the I2S handle allocation */
00271   if (hi2s == NULL)
00272   {
00273     return HAL_ERROR;
00274   }
00275 
00276   /* Check the I2S parameters */
00277   assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
00278   assert_param(IS_I2S_MODE(hi2s->Init.Mode));
00279   assert_param(IS_I2S_STANDARD(hi2s->Init.Standard));
00280   assert_param(IS_I2S_DATA_FORMAT(hi2s->Init.DataFormat));
00281   assert_param(IS_I2S_MCLK_OUTPUT(hi2s->Init.MCLKOutput));
00282   assert_param(IS_I2S_AUDIO_FREQ(hi2s->Init.AudioFreq));
00283   assert_param(IS_I2S_CPOL(hi2s->Init.CPOL));
00284   assert_param(IS_I2S_FIRST_BIT(hi2s->Init.FirstBit));
00285   assert_param(IS_I2S_WS_INVERSION(hi2s->Init.WSInversion));
00286   assert_param(IS_I2S_DATA_24BIT_ALIGNMENT(hi2s->Init.Data24BitAlignment));
00287   assert_param(IS_I2S_MASTER_KEEP_IO_STATE(hi2s->Init.MasterKeepIOState));
00288 
00289   if (hi2s->State == HAL_I2S_STATE_RESET)
00290   {
00291     /* Allocate lock resource and initialize it */
00292     hi2s->Lock = HAL_UNLOCKED;
00293 
00294 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
00295     /* Init the I2S Callback settings */
00296     hi2s->TxCpltCallback       = HAL_I2S_TxCpltCallback;          /* Legacy weak TxCpltCallback       */
00297     hi2s->RxCpltCallback       = HAL_I2S_RxCpltCallback;          /* Legacy weak RxCpltCallback       */
00298     hi2s->TxRxCpltCallback     = HAL_I2SEx_TxRxCpltCallback;      /* Legacy weak TxRxCpltCallback     */
00299     hi2s->TxHalfCpltCallback   = HAL_I2S_TxHalfCpltCallback;      /* Legacy weak TxHalfCpltCallback   */
00300     hi2s->RxHalfCpltCallback   = HAL_I2S_RxHalfCpltCallback;      /* Legacy weak RxHalfCpltCallback   */
00301     hi2s->TxRxHalfCpltCallback = HAL_I2SEx_TxRxHalfCpltCallback;  /* Legacy weak TxRxHalfCpltCallback */
00302     hi2s->ErrorCallback        = HAL_I2S_ErrorCallback;           /* Legacy weak ErrorCallback        */
00303 
00304     if (hi2s->MspInitCallback == NULL)
00305     {
00306       hi2s->MspInitCallback = HAL_I2S_MspInit; /* Legacy weak MspInit  */
00307     }
00308 
00309     /* Init the low level hardware : GPIO, CLOCK, NVIC... */
00310     hi2s->MspInitCallback(hi2s);
00311 #else
00312     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
00313     HAL_I2S_MspInit(hi2s);
00314 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
00315   }
00316 
00317   hi2s->State = HAL_I2S_STATE_BUSY;
00318 
00319   /* Disable the selected I2S peripheral */
00320   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) == SPI_CR1_SPE)
00321   {
00322     /* Disable I2S peripheral */
00323     __HAL_I2S_DISABLE(hi2s);
00324   }
00325 
00326   /* Clear I2S configuration register */
00327   CLEAR_REG(hi2s->Instance->I2SCFGR);
00328 
00329   if (IS_I2S_MASTER(hi2s->Init.Mode))
00330   {
00331     /*------------------------- I2SDIV and ODD Calculation ---------------------*/
00332     /* If the requested audio frequency is not the default, compute the prescaler */
00333     if (hi2s->Init.AudioFreq != I2S_AUDIOFREQ_DEFAULT)
00334     {
00335       /* Check the frame length (For the Prescaler computing) ********************/
00336       if (hi2s->Init.DataFormat != I2S_DATAFORMAT_16B)
00337       {
00338         /* Channel length is 32 bits */
00339         packetlength = 2UL;
00340       }
00341       else
00342       {
00343         /* Channel length is 16 bits */
00344         packetlength = 1UL;
00345       }
00346 
00347       /* Check if PCM standard is used */
00348       if ((hi2s->Init.Standard == I2S_STANDARD_PCM_SHORT) ||
00349           (hi2s->Init.Standard == I2S_STANDARD_PCM_LONG))
00350       {
00351         ispcm = 1UL;
00352       }
00353       else
00354       {
00355         ispcm = 0UL;
00356       }
00357 
00358       /* Get the source clock value: based on System Clock value */
00359 #if defined (SPI_SPI6I2S_SUPPORT)
00360       if (hi2s->Instance == SPI6)
00361       {
00362         /* SPI6 source clock */
00363         i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI6);
00364       }
00365       else
00366       {
00367         /* SPI1,SPI2 and SPI3 share the same source clock */
00368         i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI123);
00369       }
00370 #else
00371       /* SPI1,SPI2 and SPI3 share the same source clock */
00372       i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI123);
00373 #endif  /* SPI_SPI6I2S_SUPPORT */
00374 
00375       /* Compute the Real divider depending on the MCLK output state, with a floating point */
00376       if (hi2s->Init.MCLKOutput == I2S_MCLKOUTPUT_ENABLE)
00377       {
00378         /* MCLK output is enabled */
00379         tmp = (uint32_t)((((i2sclk / (256UL >> ispcm)) * 10UL) / hi2s->Init.AudioFreq) + 5UL);
00380       }
00381       else
00382       {
00383         /* MCLK output is disabled */
00384         tmp = (uint32_t)((((i2sclk / ((32UL >> ispcm) * packetlength)) * 10UL) / hi2s->Init.AudioFreq) + 5UL);
00385       }
00386 
00387       /* Remove the flatting point */
00388       tmp = tmp / 10UL;
00389 
00390       /* Check the parity of the divider */
00391       i2sodd = (uint32_t)(tmp & (uint32_t)1UL);
00392 
00393       /* Compute the i2sdiv prescaler */
00394       i2sdiv = (uint32_t)((tmp - i2sodd) / 2UL);
00395     }
00396     else
00397     {
00398       /* Set the default values */
00399       i2sdiv = 2UL;
00400       i2sodd = 0UL;
00401     }
00402 
00403     /* Test if the obtain values are forbidden or out of range */
00404     if (((i2sodd == 1UL) && (i2sdiv == 1UL)) || (i2sdiv > 0xFFUL))
00405     {
00406       /* Set the error code */
00407       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_PRESCALER);
00408       return  HAL_ERROR;
00409     }
00410 
00411     /* Force i2smod to 1 just to be sure that (2xi2sdiv + i2sodd) is always higher than 0 */
00412     if (i2sdiv == 0UL)
00413     {
00414       i2sodd = 1UL;
00415     }
00416 
00417     MODIFY_REG(hi2s->Instance->I2SCFGR, (SPI_I2SCFGR_I2SDIV                 | SPI_I2SCFGR_ODD),
00418                ((i2sdiv << SPI_I2SCFGR_I2SDIV_Pos) | (i2sodd << SPI_I2SCFGR_ODD_Pos)));
00419   }
00420 
00421   /*-------------------------- I2Sx I2SCFGR Configuration --------------------*/
00422   /* Configure I2SMOD, I2SCFG, I2SSTD, PCMSYNC, DATLEN ,CHLEN ,CKPOL, WSINV, DATAFMT, I2SDIV, ODD and MCKOE bits bits */
00423   /* And configure the I2S with the I2S_InitStruct values */
00424   MODIFY_REG(hi2s->Instance->I2SCFGR, (SPI_I2SCFGR_I2SMOD   | SPI_I2SCFGR_I2SCFG     | \
00425                                        SPI_I2SCFGR_I2SSTD   | SPI_I2SCFGR_PCMSYNC    | \
00426                                        SPI_I2SCFGR_DATLEN   | SPI_I2SCFGR_CHLEN      | \
00427                                        SPI_I2SCFGR_CKPOL    | SPI_I2SCFGR_WSINV      | \
00428                                        SPI_I2SCFGR_DATFMT   | SPI_I2SCFGR_MCKOE),
00429              (SPI_I2SCFGR_I2SMOD   | hi2s->Init.Mode        | \
00430               hi2s->Init.Standard  | hi2s->Init.DataFormat  | \
00431               hi2s->Init.CPOL      | hi2s->Init.WSInversion | \
00432               hi2s->Init.Data24BitAlignment | hi2s->Init.MCLKOutput));
00433   /*Clear status register*/
00434   WRITE_REG(hi2s->Instance->IFCR, 0x0FF8);
00435 
00436   /*---------------------------- I2Sx CFG2 Configuration ----------------------*/
00437 
00438   /* Unlock the AF configuration to configure CFG2 register*/
00439   CLEAR_BIT(hi2s->Instance->CR1, SPI_CR1_IOLOCK);
00440 
00441   MODIFY_REG(hi2s->Instance->CFG2, SPI_CFG2_LSBFRST, hi2s->Init.FirstBit);
00442 
00443   /* Insure that AFCNTR is managed only by Master */
00444   if (IS_I2S_MASTER(hi2s->Init.Mode))
00445   {
00446     /* Alternate function GPIOs control */
00447     MODIFY_REG(hi2s->Instance->CFG2, SPI_CFG2_AFCNTR, (hi2s->Init.MasterKeepIOState));
00448   }
00449 
00450   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
00451   hi2s->State     = HAL_I2S_STATE_READY;
00452 
00453   return HAL_OK;
00454 }
00455 
00456 /**
00457   * @brief DeInitializes the I2S peripheral
00458   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
00459   *         the configuration information for I2S module
00460   * @retval HAL status
00461   */
00462 HAL_StatusTypeDef HAL_I2S_DeInit(I2S_HandleTypeDef *hi2s)
00463 {
00464   /* Check the I2S handle allocation */
00465   if (hi2s == NULL)
00466   {
00467     return HAL_ERROR;
00468   }
00469 
00470   /* Check the parameters */
00471   assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
00472 
00473   hi2s->State = HAL_I2S_STATE_BUSY;
00474 
00475   /* Disable the I2S Peripheral Clock */
00476   __HAL_I2S_DISABLE(hi2s);
00477 
00478 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
00479   if (hi2s->MspDeInitCallback == NULL)
00480   {
00481     hi2s->MspDeInitCallback = HAL_I2S_MspDeInit; /* Legacy weak MspDeInit  */
00482   }
00483 
00484   /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
00485   hi2s->MspDeInitCallback(hi2s);
00486 #else
00487   /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
00488   HAL_I2S_MspDeInit(hi2s);
00489 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
00490 
00491   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
00492   hi2s->State     = HAL_I2S_STATE_RESET;
00493 
00494   /* Release Lock */
00495   __HAL_UNLOCK(hi2s);
00496 
00497   return HAL_OK;
00498 }
00499 
00500 /**
00501   * @brief I2S MSP Init
00502   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
00503   *         the configuration information for I2S module
00504   * @retval None
00505   */
00506 __weak void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s)
00507 {
00508   /* Prevent unused argument(s) compilation warning */
00509   UNUSED(hi2s);
00510 
00511   /* NOTE : This function Should not be modified, when the callback is needed,
00512             the HAL_I2S_MspInit could be implemented in the user file
00513    */
00514 }
00515 
00516 /**
00517   * @brief I2S MSP DeInit
00518   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
00519   *         the configuration information for I2S module
00520   * @retval None
00521   */
00522 __weak void HAL_I2S_MspDeInit(I2S_HandleTypeDef *hi2s)
00523 {
00524   /* Prevent unused argument(s) compilation warning */
00525   UNUSED(hi2s);
00526 
00527   /* NOTE : This function Should not be modified, when the callback is needed,
00528             the HAL_I2S_MspDeInit could be implemented in the user file
00529    */
00530 }
00531 
00532 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
00533 /**
00534   * @brief  Register a User I2S Callback
00535   *         To be used instead of the weak predefined callback
00536   * @param  hi2s Pointer to a I2S_HandleTypeDef structure that contains
00537   *                the configuration information for the specified I2S.
00538   * @param  CallbackID ID of the callback to be registered
00539   * @param  pCallback pointer to the Callback function
00540   * @retval HAL status
00541   */
00542 HAL_StatusTypeDef HAL_I2S_RegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID,
00543                                            pI2S_CallbackTypeDef pCallback)
00544 {
00545   HAL_StatusTypeDef status = HAL_OK;
00546 
00547   if (pCallback == NULL)
00548   {
00549     /* Update the error code */
00550     hi2s->ErrorCode |= HAL_I2S_ERROR_INVALID_CALLBACK;
00551 
00552     return HAL_ERROR;
00553   }
00554   /* Process locked */
00555   __HAL_LOCK(hi2s);
00556 
00557   if (HAL_I2S_STATE_READY == hi2s->State)
00558   {
00559     switch (CallbackID)
00560     {
00561       case HAL_I2S_TX_COMPLETE_CB_ID :
00562         hi2s->TxCpltCallback = pCallback;
00563         break;
00564 
00565       case HAL_I2S_RX_COMPLETE_CB_ID :
00566         hi2s->RxCpltCallback = pCallback;
00567         break;
00568 
00569       case HAL_I2S_TX_RX_COMPLETE_CB_ID :
00570         hi2s->TxRxCpltCallback = pCallback;
00571         break;
00572 
00573       case HAL_I2S_TX_HALF_COMPLETE_CB_ID :
00574         hi2s->TxHalfCpltCallback = pCallback;
00575         break;
00576 
00577       case HAL_I2S_RX_HALF_COMPLETE_CB_ID :
00578         hi2s->RxHalfCpltCallback = pCallback;
00579         break;
00580 
00581 
00582       case HAL_I2S_TX_RX_HALF_COMPLETE_CB_ID :
00583         hi2s->TxRxHalfCpltCallback = pCallback;
00584         break;
00585 
00586       case HAL_I2S_ERROR_CB_ID :
00587         hi2s->ErrorCallback = pCallback;
00588         break;
00589 
00590       case HAL_I2S_MSPINIT_CB_ID :
00591         hi2s->MspInitCallback = pCallback;
00592         break;
00593 
00594       case HAL_I2S_MSPDEINIT_CB_ID :
00595         hi2s->MspDeInitCallback = pCallback;
00596         break;
00597 
00598       default :
00599         /* Update the error code */
00600         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
00601 
00602         /* Return error status */
00603         status =  HAL_ERROR;
00604         break;
00605     }
00606   }
00607   else if (HAL_I2S_STATE_RESET == hi2s->State)
00608   {
00609     switch (CallbackID)
00610     {
00611       case HAL_I2S_MSPINIT_CB_ID :
00612         hi2s->MspInitCallback = pCallback;
00613         break;
00614 
00615       case HAL_I2S_MSPDEINIT_CB_ID :
00616         hi2s->MspDeInitCallback = pCallback;
00617         break;
00618 
00619       default :
00620         /* Update the error code */
00621         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
00622 
00623         /* Return error status */
00624         status =  HAL_ERROR;
00625         break;
00626     }
00627   }
00628   else
00629   {
00630     /* Update the error code */
00631     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
00632 
00633     /* Return error status */
00634     status =  HAL_ERROR;
00635   }
00636 
00637   /* Release Lock */
00638   __HAL_UNLOCK(hi2s);
00639   return status;
00640 }
00641 
00642 /**
00643   * @brief  Unregister an I2S Callback
00644   *         I2S callback is redirected to the weak predefined callback
00645   * @param  hi2s Pointer to a I2S_HandleTypeDef structure that contains
00646   *                the configuration information for the specified I2S.
00647   * @param  CallbackID ID of the callback to be unregistered
00648   * @retval HAL status
00649   */
00650 HAL_StatusTypeDef HAL_I2S_UnRegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID)
00651 {
00652   HAL_StatusTypeDef status = HAL_OK;
00653 
00654   /* Process locked */
00655   __HAL_LOCK(hi2s);
00656 
00657   if (HAL_I2S_STATE_READY == hi2s->State)
00658   {
00659     switch (CallbackID)
00660     {
00661       case HAL_I2S_TX_COMPLETE_CB_ID :
00662         hi2s->TxCpltCallback = HAL_I2S_TxCpltCallback;                /* Legacy weak TxCpltCallback       */
00663         break;
00664 
00665       case HAL_I2S_RX_COMPLETE_CB_ID :
00666         hi2s->RxCpltCallback = HAL_I2S_RxCpltCallback;                /* Legacy weak RxCpltCallback       */
00667         break;
00668 
00669       case HAL_I2S_TX_RX_COMPLETE_CB_ID :
00670         hi2s->TxRxCpltCallback = HAL_I2SEx_TxRxCpltCallback;          /* Legacy weak TxRxCpltCallback     */
00671         break;
00672 
00673       case HAL_I2S_TX_HALF_COMPLETE_CB_ID :
00674         hi2s->TxHalfCpltCallback = HAL_I2S_TxHalfCpltCallback;        /* Legacy weak TxHalfCpltCallback   */
00675         break;
00676 
00677       case HAL_I2S_RX_HALF_COMPLETE_CB_ID :
00678         hi2s->RxHalfCpltCallback = HAL_I2S_RxHalfCpltCallback;        /* Legacy weak RxHalfCpltCallback   */
00679         break;
00680 
00681       case HAL_I2S_TX_RX_HALF_COMPLETE_CB_ID :
00682         hi2s->TxRxHalfCpltCallback = HAL_I2SEx_TxRxHalfCpltCallback;  /* Legacy weak TxRxHalfCpltCallback */
00683         break;
00684 
00685       case HAL_I2S_ERROR_CB_ID :
00686         hi2s->ErrorCallback = HAL_I2S_ErrorCallback;                  /* Legacy weak ErrorCallback        */
00687         break;
00688 
00689       case HAL_I2S_MSPINIT_CB_ID :
00690         hi2s->MspInitCallback = HAL_I2S_MspInit;                      /* Legacy weak MspInit              */
00691         break;
00692 
00693       case HAL_I2S_MSPDEINIT_CB_ID :
00694         hi2s->MspDeInitCallback = HAL_I2S_MspDeInit;                  /* Legacy weak MspDeInit            */
00695         break;
00696 
00697       default :
00698         /* Update the error code */
00699         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
00700 
00701         /* Return error status */
00702         status =  HAL_ERROR;
00703         break;
00704     }
00705   }
00706   else if (HAL_I2S_STATE_RESET == hi2s->State)
00707   {
00708     switch (CallbackID)
00709     {
00710       case HAL_I2S_MSPINIT_CB_ID :
00711         hi2s->MspInitCallback = HAL_I2S_MspInit;                      /* Legacy weak MspInit              */
00712         break;
00713 
00714       case HAL_I2S_MSPDEINIT_CB_ID :
00715         hi2s->MspDeInitCallback = HAL_I2S_MspDeInit;                  /* Legacy weak MspDeInit            */
00716         break;
00717 
00718       default :
00719         /* Update the error code */
00720         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
00721 
00722         /* Return error status */
00723         status =  HAL_ERROR;
00724         break;
00725     }
00726   }
00727   else
00728   {
00729     /* Update the error code */
00730     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
00731 
00732     /* Return error status */
00733     status =  HAL_ERROR;
00734   }
00735 
00736   /* Release Lock */
00737   __HAL_UNLOCK(hi2s);
00738   return status;
00739 }
00740 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
00741 /**
00742   * @}
00743   */
00744 
00745 /** @defgroup I2S_Exported_Functions_Group2 IO operation functions
00746   *  @brief Data transfers functions
00747   *
00748 @verbatim
00749  ===============================================================================
00750                       ##### IO operation functions #####
00751  ===============================================================================
00752     [..]
00753     This subsection provides a set of functions allowing to manage the I2S data
00754     transfers.
00755 
00756     (#) There are two modes of transfer:
00757        (++) Blocking mode : The communication is performed in the polling mode.
00758             The status of all data processing is returned by the same function
00759             after finishing transfer.
00760        (++) No-Blocking mode : The communication is performed using Interrupts
00761             or DMA. These functions return the status of the transfer startup.
00762             The end of the data processing will be indicated through the
00763             dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when
00764             using DMA mode.
00765 
00766     (#) Blocking mode functions are :
00767         (++) HAL_I2S_Transmit()
00768         (++) HAL_I2S_Receive()
00769         (++) HAL_I2SEx_TransmitReceive()
00770 
00771     (#) No-Blocking mode functions with Interrupt are :
00772         (++) HAL_I2S_Transmit_IT()
00773         (++) HAL_I2S_Receive_IT()
00774         (++) HAL_I2SEx_TransmitReceive_IT()
00775 
00776     (#) No-Blocking mode functions with DMA are :
00777         (++) HAL_I2S_Transmit_DMA()
00778         (++) HAL_I2S_Receive_DMA()
00779         (++) HAL_I2SEx_TransmitReceive_DMA()
00780 
00781     (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
00782         (++) HAL_I2S_TxCpltCallback()
00783         (++) HAL_I2S_RxCpltCallback()
00784         (++) HAL_I2SEx_TxRxCpltCallback()
00785         (++) HAL_I2S_ErrorCallback()
00786 
00787 @endverbatim
00788   * @{
00789   */
00790 
00791 /**
00792   * @brief  Transmit an amount of data in blocking mode
00793   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
00794   *         the configuration information for I2S module
00795   * @param  pData a 16-bit pointer to data buffer.
00796   * @param  Size number of data sample to be sent:
00797   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
00798   *         configuration phase, the Size parameter means the number of 16-bit data length
00799   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
00800   *         the Size parameter means the number of 16-bit data length.
00801   * @param  Timeout Timeout duration
00802   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
00803   *         between Master and Slave(example: audio streaming).
00804   * @retval HAL status
00805   */
00806 HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
00807 {
00808 #if defined (__GNUC__)
00809   __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->TXDR));
00810 #endif /* __GNUC__ */
00811 
00812   if ((pData == NULL) || (Size == 0UL))
00813   {
00814     return  HAL_ERROR;
00815   }
00816 
00817   if (hi2s->State != HAL_I2S_STATE_READY)
00818   {
00819     return HAL_BUSY;
00820   }
00821 
00822   /* Process Locked */
00823   __HAL_LOCK(hi2s);
00824 
00825   /* Set state and reset error code */
00826   hi2s->State       = HAL_I2S_STATE_BUSY_TX;
00827   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
00828   hi2s->pTxBuffPtr  = pData;
00829   hi2s->TxXferSize  = Size;
00830   hi2s->TxXferCount = Size;
00831 
00832   /* Initialize fields not used in handle to zero */
00833   hi2s->pRxBuffPtr  = NULL;
00834   hi2s->RxXferSize  = (uint16_t) 0UL;
00835   hi2s->RxXferCount = (uint16_t) 0UL;
00836 
00837   /* Check if the I2S is already enabled */
00838   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
00839   {
00840     /* Enable I2S peripheral */
00841     __HAL_I2S_ENABLE(hi2s);
00842   }
00843 
00844   /* Start the transfer */
00845   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
00846 
00847 
00848   /* Wait until TXP flag is set */
00849   if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXP, SET, Timeout) != HAL_OK)
00850   {
00851     /* Set the error code */
00852     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
00853     hi2s->State = HAL_I2S_STATE_READY;
00854     __HAL_UNLOCK(hi2s);
00855     return HAL_TIMEOUT;
00856   }
00857 
00858   while (hi2s->TxXferCount > 0UL)
00859   {
00860     if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
00861     {
00862       /* Transmit data in 32 Bit mode */
00863       hi2s->Instance->TXDR = *((uint32_t *)hi2s->pTxBuffPtr);
00864       hi2s->pTxBuffPtr += 2;
00865       hi2s->TxXferCount--;
00866     }
00867     else
00868     {
00869       /* Transmit data in 16 Bit mode */
00870 #if defined (__GNUC__)
00871       *ptxdr_16bits = *((uint16_t *)hi2s->pTxBuffPtr);
00872 #else
00873       *((__IO uint16_t *)&hi2s->Instance->TXDR) = *((uint16_t *)hi2s->pTxBuffPtr);
00874 #endif /* __GNUC__ */
00875 
00876       hi2s->pTxBuffPtr++;
00877       hi2s->TxXferCount--;
00878     }
00879 
00880     /* Wait until TXP flag is set */
00881     if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXP, SET, Timeout) != HAL_OK)
00882     {
00883       /* Set the error code */
00884       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
00885       hi2s->State = HAL_I2S_STATE_READY;
00886       __HAL_UNLOCK(hi2s);
00887       return HAL_TIMEOUT;
00888     }
00889 
00890     /* Check if an underrun occurs */
00891     if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET)
00892     {
00893       /* Clear underrun flag */
00894       __HAL_I2S_CLEAR_UDRFLAG(hi2s);
00895 
00896       /* Set the error code */
00897       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
00898     }
00899   }
00900 
00901   hi2s->State = HAL_I2S_STATE_READY;
00902   __HAL_UNLOCK(hi2s);
00903   return HAL_OK;
00904 }
00905 
00906 /**
00907   * @brief  Receive an amount of data in blocking mode
00908   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
00909   *         the configuration information for I2S module
00910   * @param  pData a 16-bit pointer to data buffer.
00911   * @param  Size number of data sample to be sent:
00912   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
00913   *         configuration phase, the Size parameter means the number of 16-bit data length
00914   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
00915   *         the Size parameter means the number of 16-bit data length.
00916   * @param  Timeout Timeout duration
00917   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
00918   *         between Master and Slave(example: audio streaming).
00919   * @note   In I2S Master Receiver mode, just after enabling the peripheral the clock will be generate
00920   *         in continuous way and as the I2S is not disabled at the end of the I2S transaction.
00921   * @retval HAL status
00922   */
00923 HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
00924 {
00925 #if defined (__GNUC__)
00926   __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->RXDR));
00927 #endif /* __GNUC__ */
00928 
00929   if ((pData == NULL) || (Size == 0UL))
00930   {
00931     return  HAL_ERROR;
00932   }
00933 
00934   if (hi2s->State != HAL_I2S_STATE_READY)
00935   {
00936     return HAL_BUSY;
00937   }
00938 
00939   /* Process Locked */
00940   __HAL_LOCK(hi2s);
00941 
00942   /* Set state and reset error code */
00943   hi2s->State       = HAL_I2S_STATE_BUSY_RX;
00944   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
00945   hi2s->pRxBuffPtr  = pData;
00946   hi2s->RxXferSize  = Size;
00947   hi2s->RxXferCount = Size;
00948 
00949   /* Initialize fields not used in handle to zero */
00950   hi2s->pTxBuffPtr  = NULL;
00951   hi2s->TxXferSize  = (uint16_t) 0UL;
00952   hi2s->TxXferCount = (uint16_t) 0UL;
00953 
00954   /* Check if the I2S is already enabled */
00955   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
00956   {
00957     /* Enable I2S peripheral */
00958     __HAL_I2S_ENABLE(hi2s);
00959   }
00960 
00961   /* Start the transfer */
00962   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
00963 
00964   /* Receive data */
00965   while (hi2s->RxXferCount > 0UL)
00966   {
00967     /* Wait until RXP flag is set */
00968     if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXP, SET, Timeout) != HAL_OK)
00969     {
00970       /* Set the error code */
00971       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
00972       hi2s->State = HAL_I2S_STATE_READY;
00973       __HAL_UNLOCK(hi2s);
00974       return HAL_TIMEOUT;
00975     }
00976 
00977     if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
00978     {
00979       /* Receive data in 32 Bit mode */
00980       *((uint32_t *)hi2s->pRxBuffPtr) = hi2s->Instance->RXDR;
00981       hi2s->pRxBuffPtr += 2;
00982       hi2s->RxXferCount--;
00983     }
00984     else
00985     {
00986       /* Receive data in 16 Bit mode */
00987 #if defined (__GNUC__)
00988       *((uint16_t *)hi2s->pRxBuffPtr) = *prxdr_16bits;
00989 #else
00990       *((uint16_t *)hi2s->pRxBuffPtr) = *((__IO uint16_t *)&hi2s->Instance->RXDR);
00991 #endif /* __GNUC__ */
00992       hi2s->pRxBuffPtr++;
00993       hi2s->RxXferCount--;
00994     }
00995 
00996     /* Check if an overrun occurs */
00997     if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
00998     {
00999       /* Clear overrun flag */
01000       __HAL_I2S_CLEAR_OVRFLAG(hi2s);
01001 
01002       /* Set the error code */
01003       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
01004     }
01005   }
01006 
01007   hi2s->State = HAL_I2S_STATE_READY;
01008   __HAL_UNLOCK(hi2s);
01009   return HAL_OK;
01010 }
01011 
01012 /**
01013   * @brief  Full-Duplex Transmit/Receive data in blocking mode.
01014   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
01015   *         the configuration information for I2S module
01016   * @param  pTxData a 16-bit pointer to the Transmit data buffer.
01017   * @param  pRxData a 16-bit pointer to the Receive data buffer.
01018   * @param  Size number of data sample to be sent:
01019   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
01020   *         configuration phase, the Size parameter means the number of 16-bit data length
01021   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
01022   *         the Size parameter means the number of 16-bit data length.
01023   * @param  Timeout Timeout duration
01024   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
01025   *         between Master and Slave(example: audio streaming).
01026   * @retval HAL status
01027   */
01028 
01029 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData,
01030                                             uint16_t Size, uint32_t Timeout)
01031 {
01032   uint32_t tmp_TxXferCount;
01033   uint32_t tmp_RxXferCount;
01034   uint32_t tickstart;
01035 
01036 #if defined (__GNUC__)
01037   __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->TXDR));
01038   __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->RXDR));
01039 #endif /* __GNUC__ */
01040 
01041   if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
01042   {
01043     return  HAL_ERROR;
01044   }
01045 
01046   if (hi2s->State != HAL_I2S_STATE_READY)
01047   {
01048     return HAL_BUSY;
01049   }
01050 
01051   /* Process Locked */
01052   __HAL_LOCK(hi2s);
01053 
01054   /* Init tickstart for timeout management*/
01055   tickstart = HAL_GetTick();
01056 
01057   hi2s->TxXferSize  = Size;
01058   hi2s->TxXferCount = Size;
01059   hi2s->pTxBuffPtr  = pTxData;
01060   hi2s->RxXferSize  = Size;
01061   hi2s->RxXferCount = Size;
01062   hi2s->pRxBuffPtr  = pRxData;
01063 
01064   tmp_TxXferCount = hi2s->TxXferCount;
01065   tmp_RxXferCount = hi2s->RxXferCount;
01066 
01067   /* Set state and reset error code */
01068   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
01069   hi2s->State = HAL_I2S_STATE_BUSY_TX_RX;
01070 
01071   /* Check if the I2S is already enabled */
01072   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
01073   {
01074     /* Enable I2S peripheral */
01075     __HAL_I2S_ENABLE(hi2s);
01076   }
01077 
01078   /* Start the transfer */
01079   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
01080 
01081   while ((tmp_TxXferCount > 0UL) || (tmp_RxXferCount > 0UL))
01082   {
01083     if ((__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_TXP) == SET) && (tmp_TxXferCount != 0UL))
01084     {
01085       if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
01086       {
01087         /* Transmit data in 32 Bit mode */
01088         hi2s->Instance->TXDR = *((uint32_t *)hi2s->pTxBuffPtr);
01089         hi2s->pTxBuffPtr += 2;
01090         tmp_TxXferCount--;
01091       }
01092       else
01093       {
01094         /* Transmit data in 16 Bit mode */
01095 #if defined (__GNUC__)
01096         *ptxdr_16bits = *((uint16_t *)hi2s->pTxBuffPtr);
01097 #else
01098         *((__IO uint16_t *)&hi2s->Instance->TXDR) = *((uint16_t *)hi2s->pTxBuffPtr);
01099 #endif /* __GNUC__ */
01100 
01101         hi2s->pTxBuffPtr++;
01102         tmp_TxXferCount--;
01103       }
01104 
01105       /* Check if an underrun occurs */
01106       if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET)
01107       {
01108         /* Clear underrun flag */
01109         __HAL_I2S_CLEAR_UDRFLAG(hi2s);
01110 
01111         /* Set the error code */
01112         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
01113       }
01114     }
01115 
01116     if ((__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_RXP) == SET) && (tmp_RxXferCount != 0UL))
01117     {
01118       if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
01119       {
01120         /* Receive data in 32 Bit mode */
01121         *((uint32_t *)hi2s->pRxBuffPtr) = hi2s->Instance->RXDR;
01122         hi2s->pRxBuffPtr += 2;
01123         tmp_RxXferCount--;
01124       }
01125       else
01126       {
01127         /* Receive data in 16 Bit mode */
01128 #if defined (__GNUC__)
01129         *((uint16_t *)hi2s->pRxBuffPtr) = *prxdr_16bits;
01130 #else
01131         *((uint16_t *)hi2s->pRxBuffPtr) = *((__IO uint16_t *)&hi2s->Instance->RXDR);
01132 #endif /* __GNUC__ */
01133         hi2s->pRxBuffPtr++;
01134         tmp_RxXferCount--;
01135       }
01136 
01137       /* Check if an overrun occurs */
01138       if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
01139       {
01140         /* Clear overrun flag */
01141         __HAL_I2S_CLEAR_OVRFLAG(hi2s);
01142 
01143         /* Set the error code */
01144         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
01145       }
01146     }
01147 
01148     /* Timeout management */
01149     if ((((HAL_GetTick() - tickstart) >=  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
01150     {
01151       /* Set the error code */
01152       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
01153       hi2s->State = HAL_I2S_STATE_READY;
01154       __HAL_UNLOCK(hi2s);
01155       return HAL_TIMEOUT;
01156     }
01157   }
01158 
01159   hi2s->State = HAL_I2S_STATE_READY;
01160   __HAL_UNLOCK(hi2s);
01161   return HAL_OK;
01162 }
01163 
01164 /**
01165   * @brief  Transmit an amount of data in non-blocking mode with Interrupt
01166   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
01167   *         the configuration information for I2S module
01168   * @param  pData a 16-bit pointer to data buffer.
01169   * @param  Size number of data sample to be sent:
01170   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
01171   *         configuration phase, the Size parameter means the number of 16-bit data length
01172   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
01173   *         the Size parameter means the number of 16-bit data length.
01174   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
01175   *         between Master and Slave(example: audio streaming).
01176   * @retval HAL status
01177   */
01178 HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
01179 {
01180   if ((pData == NULL) || (Size == 0UL))
01181   {
01182     return  HAL_ERROR;
01183   }
01184 
01185   if (hi2s->State != HAL_I2S_STATE_READY)
01186   {
01187     return HAL_BUSY;
01188   }
01189 
01190   /* Process Locked */
01191   __HAL_LOCK(hi2s);
01192 
01193   /* Set state and reset error code */
01194   hi2s->State       = HAL_I2S_STATE_BUSY_TX;
01195   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
01196   hi2s->pTxBuffPtr  = (uint16_t *)pData;
01197   hi2s->TxXferSize  = Size;
01198   hi2s->TxXferCount = Size;
01199 
01200   /* Initialize fields not used in handle to zero */
01201   hi2s->pRxBuffPtr  = NULL;
01202   hi2s->RxXferSize  = (uint16_t) 0UL;
01203   hi2s->RxXferCount = (uint16_t) 0UL;
01204 
01205   /* Set the function for IT treatment */
01206   if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
01207   {
01208     hi2s->TxISR = I2S_Transmit_32Bit_IT;
01209   }
01210   else
01211   {
01212     hi2s->TxISR = I2S_Transmit_16Bit_IT;
01213   }
01214 
01215   /* Check if the I2S is already enabled */
01216   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
01217   {
01218     /* Enable I2S peripheral */
01219     __HAL_I2S_ENABLE(hi2s);
01220   }
01221 
01222   /* Enable TXP and UDR interrupt */
01223   __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_UDR));
01224 
01225   /* Enable TIFRE interrupt if the mode is Slave  */
01226   if (hi2s->Init.Mode == I2S_MODE_SLAVE_TX)
01227   {
01228     __HAL_I2S_ENABLE_IT(hi2s, I2S_IT_FRE);
01229   }
01230 
01231   /* Start the transfer */
01232   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
01233 
01234   __HAL_UNLOCK(hi2s);
01235   return HAL_OK;
01236 }
01237 
01238 /**
01239   * @brief  Receive an amount of data in non-blocking mode with Interrupt
01240   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
01241   *         the configuration information for I2S module
01242   * @param  pData a 16-bit pointer to the Receive data buffer.
01243   * @param  Size number of data sample to be sent:
01244   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
01245   *         configuration phase, the Size parameter means the number of 16-bit data length
01246   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
01247   *         the Size parameter means the number of 16-bit data length.
01248   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
01249   *         between Master and Slave(example: audio streaming).
01250   * @note   It is recommended to use DMA for the I2S receiver to avoid de-synchronization
01251   * between Master and Slave otherwise the I2S interrupt should be optimized.
01252   * @retval HAL status
01253   */
01254 HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
01255 {
01256   if ((pData == NULL) || (Size == 0UL))
01257   {
01258     return  HAL_ERROR;
01259   }
01260 
01261   if (hi2s->State != HAL_I2S_STATE_READY)
01262   {
01263     return HAL_BUSY;
01264   }
01265 
01266   /* Process Locked */
01267   __HAL_LOCK(hi2s);
01268 
01269   /* Set state and reset error code */
01270   hi2s->State       = HAL_I2S_STATE_BUSY_RX;
01271   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
01272   hi2s->pRxBuffPtr  = pData;
01273   hi2s->RxXferSize  = Size;
01274   hi2s->RxXferCount = Size;
01275 
01276   /* Initialize fields not used in handle to zero */
01277   hi2s->pTxBuffPtr  = NULL;
01278   hi2s->TxXferSize  = (uint16_t) 0UL;
01279   hi2s->TxXferCount = (uint16_t) 0UL;
01280 
01281   /* Set the function for IT treatment */
01282   if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
01283   {
01284     hi2s->RxISR = I2S_Receive_32Bit_IT;
01285   }
01286   else
01287   {
01288     hi2s->RxISR = I2S_Receive_16Bit_IT;
01289   }
01290 
01291   /* Check if the I2S is already enabled */
01292   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
01293   {
01294     /* Enable I2S peripheral */
01295     __HAL_I2S_ENABLE(hi2s);
01296   }
01297   /* Enable RXP and ERR interrupt */
01298   __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXP | I2S_IT_OVR));
01299 
01300   /* Enable TIFRE interrupt if the mode is Slave  */
01301   if (hi2s->Init.Mode == I2S_MODE_SLAVE_RX)
01302   {
01303     __HAL_I2S_ENABLE_IT(hi2s, I2S_IT_FRE);
01304   }
01305 
01306   /* Start the transfer */
01307   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
01308 
01309   __HAL_UNLOCK(hi2s);
01310   return HAL_OK;
01311 }
01312 
01313 /**
01314   * @brief  Full-Duplex Transmit/Receive data in non-blocking mode using Interrupt
01315   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
01316   *         the configuration information for I2S module
01317   * @param  pTxData a 16-bit pointer to the Transmit data buffer.
01318   * @param  pRxData a 16-bit pointer to the Receive data buffer.
01319   * @param  Size number of data sample to be sent:
01320   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
01321   *         configuration phase, the Size parameter means the number of 16-bit data length
01322   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
01323   *         the Size parameter means the number of 16-bit data length.
01324   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
01325   *         between Master and Slave(example: audio streaming).
01326   * @retval HAL status
01327   */
01328 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData,
01329                                                uint16_t Size)
01330 {
01331   if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
01332   {
01333     return  HAL_ERROR;
01334   }
01335 
01336   if (hi2s->State != HAL_I2S_STATE_READY)
01337   {
01338     return HAL_BUSY;
01339   }
01340 
01341   /* Process Locked */
01342   __HAL_LOCK(hi2s);
01343 
01344   hi2s->pTxBuffPtr = pTxData;
01345   hi2s->pRxBuffPtr = pRxData;
01346 
01347   hi2s->TxXferSize  = Size;
01348   hi2s->TxXferCount = Size;
01349   hi2s->RxXferSize  = Size;
01350   hi2s->RxXferCount = Size;
01351 
01352   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
01353   hi2s->State     = HAL_I2S_STATE_BUSY_TX_RX;
01354 
01355 
01356   /* Set the function for IT treatment */
01357   if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
01358   {
01359     hi2s->TxISR = I2S_Transmit_32Bit_IT;
01360     hi2s->RxISR = I2S_Receive_32Bit_IT;
01361   }
01362   else
01363   {
01364     hi2s->TxISR = I2S_Transmit_16Bit_IT;
01365     hi2s->RxISR = I2S_Receive_16Bit_IT;
01366   }
01367 
01368   /* Check if the I2S is already enabled */
01369   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
01370   {
01371     /* Enable I2S peripheral */
01372     __HAL_I2S_ENABLE(hi2s);
01373   }
01374 
01375   /* Enable TXP, RXP, DXP, UDR, OVR interrupts */
01376   __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_RXP | I2S_IT_DXP | I2S_IT_UDR | I2S_IT_OVR));
01377 
01378   /* Enable TIFRE interrupt if the mode is Slave  */
01379   if (hi2s->Init.Mode == I2S_MODE_SLAVE_FULLDUPLEX)
01380   {
01381     __HAL_I2S_ENABLE_IT(hi2s, I2S_IT_FRE);
01382   }
01383 
01384   /* Start the transfer */
01385   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
01386 
01387   __HAL_UNLOCK(hi2s);
01388   return HAL_OK;
01389 
01390 }
01391 
01392 /**
01393   * @brief  Transmit an amount of data in non-blocking mode with DMA
01394   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
01395   *         the configuration information for I2S module
01396   * @param  pData a 16-bit pointer to the Transmit data buffer.
01397   * @param  Size number of data sample to be sent:
01398   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
01399   *         configuration phase, the Size parameter means the number of 16-bit data length
01400   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
01401   *         the Size parameter means the number of 16-bit data length.
01402   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
01403   *         between Master and Slave(example: audio streaming).
01404   * @retval HAL status
01405   */
01406 HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
01407 {
01408   HAL_StatusTypeDef errorcode = HAL_OK;
01409 
01410   if ((pData == NULL) || (Size == 0UL))
01411   {
01412     return  HAL_ERROR;
01413   }
01414 
01415   if (hi2s->State != HAL_I2S_STATE_READY)
01416   {
01417     return HAL_BUSY;
01418   }
01419 
01420   /* Process Locked */
01421   __HAL_LOCK(hi2s);
01422 
01423   /* Set state and reset error code */
01424   hi2s->State       = HAL_I2S_STATE_BUSY_TX;
01425   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
01426   hi2s->pTxBuffPtr  = pData;
01427   hi2s->TxXferSize  = Size;
01428   hi2s->TxXferCount = Size;
01429 
01430   /* Init field not used in handle to zero */
01431   hi2s->pRxBuffPtr  = NULL;
01432   hi2s->RxXferSize  = (uint16_t)0UL;
01433   hi2s->RxXferCount = (uint16_t)0UL;
01434 
01435   /* Set the I2S Tx DMA Half transfer complete callback */
01436   hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt;
01437 
01438   /* Set the I2S Tx DMA transfer complete callback */
01439   hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt;
01440 
01441   /* Set the DMA error callback */
01442   hi2s->hdmatx->XferErrorCallback = I2S_DMAError;
01443 
01444   /* Enable the Tx DMA Stream/Channel */
01445   if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmatx, (uint32_t)hi2s->pTxBuffPtr, (uint32_t)&hi2s->Instance->TXDR,
01446                                  hi2s->TxXferCount))
01447   {
01448     /* Update I2S error code */
01449     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
01450     hi2s->State = HAL_I2S_STATE_READY;
01451 
01452     __HAL_UNLOCK(hi2s);
01453     errorcode = HAL_ERROR;
01454     return errorcode;
01455   }
01456 
01457   /* Check if the I2S Tx request is already enabled */
01458   if (HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN))
01459   {
01460     /* Enable Tx DMA Request */
01461     SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
01462   }
01463 
01464   /* Check if the I2S is already enabled */
01465   if (HAL_IS_BIT_CLR(hi2s->Instance->CR1, SPI_CR1_SPE))
01466   {
01467     /* Enable I2S peripheral */
01468     __HAL_I2S_ENABLE(hi2s);
01469   }
01470 
01471   /* Start the transfer */
01472   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
01473 
01474   __HAL_UNLOCK(hi2s);
01475   return errorcode;
01476 }
01477 
01478 /**
01479   * @brief  Receive an amount of data in non-blocking mode with DMA
01480   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
01481   *         the configuration information for I2S module
01482   * @param  pData a 16-bit pointer to the Receive data buffer.
01483   * @param  Size number of data sample to be sent:
01484   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
01485   *         configuration phase, the Size parameter means the number of 16-bit data length
01486   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
01487   *         the Size parameter means the number of 16-bit data length.
01488   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
01489   *         between Master and Slave(example: audio streaming).
01490   * @retval HAL status
01491   */
01492 HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
01493 {
01494   HAL_StatusTypeDef errorcode = HAL_OK;
01495 
01496   if ((pData == NULL) || (Size == 0UL))
01497   {
01498     return HAL_ERROR;
01499   }
01500 
01501   if (hi2s->State != HAL_I2S_STATE_READY)
01502   {
01503     return HAL_BUSY;
01504   }
01505 
01506   /* Process Locked */
01507   __HAL_LOCK(hi2s);
01508 
01509   /* Set state and reset error code */
01510   hi2s->State       = HAL_I2S_STATE_BUSY_RX;
01511   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
01512   hi2s->pRxBuffPtr  = pData;
01513   hi2s->RxXferSize  = Size;
01514   hi2s->RxXferCount = Size;
01515 
01516   /* Init field not used in handle to zero */
01517   hi2s->pTxBuffPtr  = NULL;
01518   hi2s->TxXferSize  = (uint16_t)0UL;
01519   hi2s->TxXferCount = (uint16_t)0UL;
01520 
01521 
01522   /* Set the I2S Rx DMA Half transfer complete callback */
01523   hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt;
01524 
01525   /* Set the I2S Rx DMA transfer complete callback */
01526   hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt;
01527 
01528   /* Set the DMA error callback */
01529   hi2s->hdmarx->XferErrorCallback = I2S_DMAError;
01530 
01531   /* Enable the Rx DMA Stream/Channel */
01532   if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->RXDR, (uint32_t)hi2s->pRxBuffPtr,
01533                                                 hi2s->RxXferCount))
01534   {
01535     /* Update I2S error code */
01536     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
01537     hi2s->State = HAL_I2S_STATE_READY;
01538     errorcode = HAL_ERROR;
01539     __HAL_UNLOCK(hi2s);
01540     return HAL_ERROR;
01541   }
01542 
01543   /* Check if the I2S Rx request is already enabled */
01544   if (HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN))
01545   {
01546     /* Enable Rx DMA Request */
01547     SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
01548   }
01549 
01550   /* Check if the I2S is already enabled */
01551   if (HAL_IS_BIT_CLR(hi2s->Instance->CR1, SPI_CR1_SPE))
01552   {
01553     /* Enable I2S peripheral */
01554     __HAL_I2S_ENABLE(hi2s);
01555   }
01556 
01557   /* Start the transfer */
01558   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
01559 
01560   __HAL_UNLOCK(hi2s);
01561   return errorcode;
01562 }
01563 
01564 /**
01565   * @brief  Full-Duplex Transmit/Receive data in non-blocking mode using DMA
01566   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
01567   *         the configuration information for I2S module
01568   * @param  pTxData a 16-bit pointer to the Transmit data buffer.
01569   * @param  pRxData a 16-bit pointer to the Receive data buffer.
01570   * @param  Size number of data sample to be sent:
01571   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
01572   *         configuration phase, the Size parameter means the number of 16-bit data length
01573   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
01574   *         the Size parameter means the number of 16-bit data length.
01575   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
01576   *         between Master and Slave(example: audio streaming).
01577   * @retval HAL status
01578   */
01579 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData,
01580                                                 uint16_t Size)
01581 {
01582   HAL_StatusTypeDef errorcode = HAL_OK;
01583 
01584 
01585   if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
01586   {
01587     return  HAL_ERROR;
01588   }
01589 
01590   if (hi2s->State != HAL_I2S_STATE_READY)
01591   {
01592     return HAL_BUSY;
01593   }
01594 
01595   /* Process Locked */
01596   __HAL_LOCK(hi2s);
01597 
01598   hi2s->pTxBuffPtr = pTxData;
01599   hi2s->pRxBuffPtr = pRxData;
01600 
01601   hi2s->TxXferSize  = Size;
01602   hi2s->TxXferCount = Size;
01603   hi2s->RxXferSize  = Size;
01604   hi2s->RxXferCount = Size;
01605 
01606   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
01607   hi2s->State       = HAL_I2S_STATE_BUSY_TX_RX;
01608 
01609   /* Reset the Tx/Rx DMA bits */
01610   CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN);
01611 
01612   /* Set the I2S Rx DMA Half transfer complete callback */
01613   hi2s->hdmarx->XferHalfCpltCallback = I2SEx_DMATxRxHalfCplt;
01614 
01615   /* Set the I2S Rx DMA transfer complete callback */
01616   hi2s->hdmarx->XferCpltCallback  = I2SEx_DMATxRxCplt;
01617 
01618   /* Set the I2S Rx DMA error callback */
01619   hi2s->hdmarx->XferErrorCallback = I2S_DMAError;
01620   /* Enable the Tx DMA Stream/Channel */
01621   if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmatx, (uint32_t)hi2s->pTxBuffPtr, (uint32_t)&hi2s->Instance->TXDR,
01622                                  hi2s->TxXferCount))
01623   {
01624     /* Update I2S error code */
01625     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
01626     hi2s->State = HAL_I2S_STATE_READY;
01627 
01628     __HAL_UNLOCK(hi2s);
01629     errorcode = HAL_ERROR;
01630     return errorcode;
01631   }
01632 
01633   /* Check if the I2S Tx request is already enabled */
01634   if (HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN))
01635   {
01636     /* Enable Tx DMA Request */
01637     SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
01638   }
01639 
01640   /* Enable the Rx DMA Stream/Channel */
01641   if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->RXDR, (uint32_t)hi2s->pRxBuffPtr,
01642                                  hi2s->RxXferCount))
01643   {
01644     /* Update I2S error code */
01645     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
01646     hi2s->State = HAL_I2S_STATE_READY;
01647     errorcode = HAL_ERROR;
01648     __HAL_UNLOCK(hi2s);
01649     return HAL_ERROR;
01650   }
01651 
01652   /* Check if the I2S Rx request is already enabled */
01653   if (HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN))
01654   {
01655     /* Enable Rx DMA Request */
01656     SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
01657   }
01658 
01659   /* Check if the I2S is already enabled */
01660   if (HAL_IS_BIT_CLR(hi2s->Instance->CR1, SPI_CR1_SPE))
01661   {
01662     /* Enable I2S peripheral */
01663     __HAL_I2S_ENABLE(hi2s);
01664   }
01665 
01666   /* Start the transfer */
01667   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
01668 
01669   __HAL_UNLOCK(hi2s);
01670   return errorcode;
01671 }
01672 
01673 /**
01674   * @brief  Pauses the audio DMA Stream/Channel playing from the Media.
01675   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
01676   *         the configuration information for I2S module
01677   * @retval HAL status
01678   */
01679 HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s)
01680 {
01681   /* Process Locked */
01682   __HAL_LOCK(hi2s);
01683 
01684   uint32_t tickstart;
01685 
01686   /* Get tick */
01687   tickstart = HAL_GetTick();
01688 
01689 
01690   /* Check if the I2S peripheral is in master mode */
01691   if (IS_I2S_MASTER(hi2s->Init.Mode))
01692   {
01693     /* Check if there is a transfer on-going */
01694     if (HAL_IS_BIT_SET(hi2s->Instance->CR1, SPI_CR1_CSTART) == 0UL)
01695     {
01696       /* Set error code to no on going transfer */
01697       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_NO_OGT);
01698       hi2s->State = HAL_I2S_STATE_READY;
01699 
01700       __HAL_UNLOCK(hi2s);
01701       return HAL_ERROR;
01702     }
01703 
01704     SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSUSP);
01705 
01706     while (HAL_IS_BIT_SET(hi2s->Instance->CR1, SPI_CR1_CSTART) != 0UL)
01707     {
01708       if ((((HAL_GetTick() - tickstart) >=  I2S_TIMEOUT) && (I2S_TIMEOUT != HAL_MAX_DELAY)) || (I2S_TIMEOUT == 0U))
01709       {
01710         /* Set the I2S State ready */
01711         hi2s->State = HAL_I2S_STATE_READY;
01712 
01713         /* Process Unlocked */
01714         __HAL_UNLOCK(hi2s);
01715 
01716         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
01717         hi2s->State = HAL_I2S_STATE_READY;
01718         return HAL_TIMEOUT;
01719       }
01720     }
01721 
01722     /* Disable I2S peripheral */
01723     __HAL_I2S_DISABLE(hi2s);
01724 
01725     hi2s->State = HAL_I2S_STATE_READY;
01726 
01727     /* Process Unlocked */
01728     __HAL_UNLOCK(hi2s);
01729 
01730     return HAL_OK;
01731   }
01732   else
01733   {
01734     /* Set error code to not supported */
01735     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_NOT_SUPPORTED);
01736     hi2s->State = HAL_I2S_STATE_READY;
01737 
01738     /* Process Unlocked */
01739     __HAL_UNLOCK(hi2s);
01740 
01741     return HAL_ERROR;
01742   }
01743 }
01744 
01745 /**
01746   * @brief  Resumes the audio DMA Stream/Channel playing from the Media.
01747   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
01748   *         the configuration information for I2S module
01749   * @retval HAL status
01750   */
01751 HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s)
01752 {
01753   /* Process Locked */
01754   __HAL_LOCK(hi2s);
01755 
01756   if (hi2s->State != HAL_I2S_STATE_READY)
01757   {
01758     hi2s->State = HAL_I2S_STATE_READY;
01759 
01760     __HAL_UNLOCK(hi2s);
01761     return HAL_ERROR;
01762   }
01763 
01764   /* Set state and reset error code */
01765   hi2s->State       = HAL_I2S_STATE_BUSY;
01766   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
01767 
01768   /* Enable I2S peripheral */
01769   __HAL_I2S_ENABLE(hi2s);
01770 
01771   /* Start the transfer */
01772   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
01773 
01774   /* Process Unlocked */
01775   __HAL_UNLOCK(hi2s);
01776 
01777   return HAL_OK;
01778 }
01779 
01780 /**
01781   * @brief  Stops the audio DMA Stream/Channel playing from the Media.
01782   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
01783   *         the configuration information for I2S module
01784   * @retval HAL status
01785   */
01786 HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s)
01787 {
01788   HAL_StatusTypeDef errorcode = HAL_OK;
01789   /* The Lock is not implemented on this API to allow the user application
01790      to call the HAL I2S API under callbacks HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback()
01791      when calling HAL_DMA_Abort() API the DMA TX or RX Transfer complete interrupt is generated
01792      and the correspond call back is executed HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback()
01793      */
01794 
01795   /* Disable the I2S Tx/Rx DMA requests */
01796   CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
01797   CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
01798 
01799   /* Abort the I2S DMA tx Stream/Channel */
01800   if (hi2s->hdmatx != NULL)
01801   {
01802     /* Disable the I2S DMA tx Stream/Channel */
01803     if (HAL_OK != HAL_DMA_Abort(hi2s->hdmatx))
01804     {
01805       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
01806       errorcode = HAL_ERROR;
01807     }
01808   }
01809 
01810   /* Abort the I2S DMA rx Stream/Channel */
01811   if (hi2s->hdmarx != NULL)
01812   {
01813     /* Disable the I2S DMA rx Stream/Channel */
01814     if (HAL_OK != HAL_DMA_Abort(hi2s->hdmarx))
01815     {
01816       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
01817       errorcode = HAL_ERROR;
01818     }
01819   }
01820 
01821   /* Disable I2S peripheral */
01822   __HAL_I2S_DISABLE(hi2s);
01823 
01824   hi2s->State = HAL_I2S_STATE_READY;
01825 
01826   return errorcode;
01827 }
01828 
01829 /**
01830   * @brief  This function handles I2S interrupt request.
01831   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
01832   *         the configuration information for I2S module
01833   * @retval None
01834   */
01835 void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s)
01836 {
01837   uint32_t i2sier   = hi2s->Instance->IER;
01838   uint32_t i2ssr    = hi2s->Instance->SR;
01839   uint32_t trigger  = i2sier & i2ssr;
01840 
01841   if (hi2s->State == HAL_I2S_STATE_BUSY_RX)
01842   {
01843     /* I2S in mode Receiver ------------------------------------------------*/
01844     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_RXP) && HAL_IS_BIT_CLR(trigger, I2S_FLAG_OVR))
01845     {
01846       hi2s->RxISR(hi2s);
01847     }
01848 
01849     /* I2S Overrun error interrupt occurred -------------------------------------*/
01850     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_OVR))
01851     {
01852       /* Disable RXP and ERR interrupt */
01853       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXP | I2S_IT_ERR));
01854 
01855       /* Clear Overrun flag */
01856       __HAL_I2S_CLEAR_OVRFLAG(hi2s);
01857 
01858       /* Set the I2S State ready */
01859       hi2s->State = HAL_I2S_STATE_READY;
01860 
01861 
01862       /* Set the error code and execute error callback*/
01863       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
01864       /* Call user error callback */
01865 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
01866       hi2s->ErrorCallback(hi2s);
01867 #else
01868       HAL_I2S_ErrorCallback(hi2s);
01869 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
01870     }
01871   }
01872 
01873   if (hi2s->State == HAL_I2S_STATE_BUSY_TX)
01874   {
01875     /* I2S in mode Transmitter -----------------------------------------------*/
01876     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_TXP) && HAL_IS_BIT_CLR(trigger, I2S_FLAG_UDR))
01877     {
01878       hi2s->TxISR(hi2s);
01879     }
01880 
01881     /* I2S Underrun error interrupt occurred --------------------------------*/
01882     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_UDR))
01883     {
01884       /* Disable TXP and ERR interrupt */
01885       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_ERR));
01886 
01887       /* Clear Underrun flag */
01888       __HAL_I2S_CLEAR_UDRFLAG(hi2s);
01889 
01890       /* Set the I2S State ready */
01891       hi2s->State = HAL_I2S_STATE_READY;
01892 
01893       /* Set the error code and execute error callback*/
01894       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
01895       /* Call user error callback */
01896 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
01897       hi2s->ErrorCallback(hi2s);
01898 #else
01899       HAL_I2S_ErrorCallback(hi2s);
01900 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
01901     }
01902   }
01903   if (hi2s->State == HAL_I2S_STATE_BUSY_TX_RX)
01904   {
01905     /* I2S in mode Transmitter -----------------------------------------------*/
01906     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_DXP))
01907     {
01908       hi2s->TxISR(hi2s);
01909       hi2s->RxISR(hi2s);
01910     }
01911     /* I2S in mode Receiver ------------------------------------------------*/
01912     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_RXP) && HAL_IS_BIT_CLR(trigger, I2S_FLAG_DXP))
01913     {
01914       hi2s->RxISR(hi2s);
01915     }
01916     /* I2S in mode Transmitter -----------------------------------------------*/
01917     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_TXP) && HAL_IS_BIT_CLR(trigger, I2S_FLAG_DXP))
01918     {
01919       hi2s->TxISR(hi2s);
01920     }
01921 
01922     /* I2S Underrun error interrupt occurred --------------------------------*/
01923     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_UDR))
01924     {
01925       /* Disable TXP and ERR interrupt */
01926       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_ERR));
01927 
01928       /* Clear Underrun flag */
01929       __HAL_I2S_CLEAR_UDRFLAG(hi2s);
01930 
01931       /* Set the I2S State ready */
01932       hi2s->State = HAL_I2S_STATE_READY;
01933 
01934       /* Set the error code and execute error callback*/
01935       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
01936       /* Call user error callback */
01937 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
01938       hi2s->ErrorCallback(hi2s);
01939 #else
01940       HAL_I2S_ErrorCallback(hi2s);
01941 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
01942     }
01943 
01944     /* I2S Overrun error interrupt occurred -------------------------------------*/
01945     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_OVR))
01946     {
01947       /* Disable RXP and ERR interrupt */
01948       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXP | I2S_IT_ERR));
01949 
01950       /* Clear Overrun flag */
01951       __HAL_I2S_CLEAR_OVRFLAG(hi2s);
01952 
01953       /* Set the I2S State ready */
01954       hi2s->State = HAL_I2S_STATE_READY;
01955 
01956 
01957       /* Set the error code and execute error callback*/
01958       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
01959 
01960       /* Call user error callback */
01961 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
01962       hi2s->ErrorCallback(hi2s);
01963 #else
01964       HAL_I2S_ErrorCallback(hi2s);
01965 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
01966     }
01967   }
01968 }
01969 
01970 /**
01971   * @brief  Tx Transfer Half completed callbacks
01972   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
01973   *         the configuration information for I2S module
01974   * @retval None
01975   */
01976 __weak void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
01977 {
01978   /* Prevent unused argument(s) compilation warning */
01979   UNUSED(hi2s);
01980 
01981   /* NOTE : This function Should not be modified, when the callback is needed,
01982             the HAL_I2S_TxHalfCpltCallback could be implemented in the user file
01983    */
01984 }
01985 
01986 /**
01987   * @brief  Tx Transfer completed callbacks
01988   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
01989   *         the configuration information for I2S module
01990   * @retval None
01991   */
01992 __weak void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
01993 {
01994   /* Prevent unused argument(s) compilation warning */
01995   UNUSED(hi2s);
01996 
01997   /* NOTE : This function Should not be modified, when the callback is needed,
01998             the HAL_I2S_TxCpltCallback could be implemented in the user file
01999    */
02000 }
02001 
02002 /**
02003   * @brief  Rx Transfer half completed callbacks
02004   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
02005   *         the configuration information for I2S module
02006   * @retval None
02007   */
02008 __weak void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
02009 {
02010   /* Prevent unused argument(s) compilation warning */
02011   UNUSED(hi2s);
02012 
02013   /* NOTE : This function Should not be modified, when the callback is needed,
02014             the HAL_I2S_RxHalfCpltCallback could be implemented in the user file
02015    */
02016 }
02017 
02018 /**
02019   * @brief  Rx Transfer completed callbacks
02020   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
02021   *         the configuration information for I2S module
02022   * @retval None
02023   */
02024 __weak void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
02025 {
02026   /* Prevent unused argument(s) compilation warning */
02027   UNUSED(hi2s);
02028 
02029   /* NOTE : This function Should not be modified, when the callback is needed,
02030             the HAL_I2S_RxCpltCallback could be implemented in the user file
02031    */
02032 }
02033 
02034 /**
02035   * @brief  Rx Transfer half completed callbacks
02036   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
02037   *         the configuration information for I2S module
02038   * @retval None
02039   */
02040 __weak void HAL_I2SEx_TxRxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
02041 {
02042   /* Prevent unused argument(s) compilation warning */
02043   UNUSED(hi2s);
02044 
02045   /* NOTE : This function Should not be modified, when the callback is needed,
02046             the HAL_I2S_RxHalfCpltCallback could be implemented in the user file
02047    */
02048 }
02049 
02050 /**
02051   * @brief  Rx Transfer completed callbacks
02052   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
02053   *         the configuration information for I2S module
02054   * @retval None
02055   */
02056 __weak void HAL_I2SEx_TxRxCpltCallback(I2S_HandleTypeDef *hi2s)
02057 {
02058   /* Prevent unused argument(s) compilation warning */
02059   UNUSED(hi2s);
02060 
02061   /* NOTE : This function Should not be modified, when the callback is needed,
02062             the HAL_I2S_RxCpltCallback could be implemented in the user file
02063    */
02064 }
02065 
02066 /**
02067   * @brief  I2S error callbacks
02068   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
02069   *         the configuration information for I2S module
02070   * @retval None
02071   */
02072 __weak void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s)
02073 {
02074   /* Prevent unused argument(s) compilation warning */
02075   UNUSED(hi2s);
02076 
02077   /* NOTE : This function Should not be modified, when the callback is needed,
02078             the HAL_I2S_ErrorCallback could be implemented in the user file
02079    */
02080 }
02081 
02082 /**
02083   * @}
02084   */
02085 
02086 /** @defgroup I2S_Exported_Functions_Group3 Peripheral State and Errors functions
02087   *  @brief   Peripheral State functions
02088   *
02089 @verbatim
02090  ===============================================================================
02091                       ##### Peripheral State and Errors functions #####
02092  ===============================================================================
02093     [..]
02094     This subsection permits to get in run-time the status of the peripheral
02095     and the data flow.
02096 
02097 @endverbatim
02098   * @{
02099   */
02100 
02101 /**
02102   * @brief  Return the I2S state
02103   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
02104   *         the configuration information for I2S module
02105   * @retval HAL state
02106   */
02107 HAL_I2S_StateTypeDef HAL_I2S_GetState(I2S_HandleTypeDef *hi2s)
02108 {
02109   return hi2s->State;
02110 }
02111 
02112 /**
02113   * @brief  Return the I2S error code
02114   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
02115   *         the configuration information for I2S module
02116   * @retval I2S Error Code
02117   */
02118 uint32_t HAL_I2S_GetError(I2S_HandleTypeDef *hi2s)
02119 {
02120   return hi2s->ErrorCode;
02121 }
02122 /**
02123   * @}
02124   */
02125 
02126 
02127 /**
02128   * @brief  DMA I2S transmit process complete callback
02129   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
02130   *                the configuration information for the specified DMA module.
02131   * @retval None
02132   */
02133 static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma)
02134 {
02135   /* Derogation MISRAC2012-Rule-11.5 */
02136   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
02137 
02138   /* if DMA is configured in DMA_NORMAL Mode */
02139   if (hdma->Init.Mode == DMA_NORMAL)
02140   {
02141     /* Disable Tx DMA Request */
02142     CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
02143 
02144     hi2s->TxXferCount = (uint16_t) 0UL;
02145     hi2s->State = HAL_I2S_STATE_READY;
02146   }
02147   /* Call user Tx complete callback */
02148 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
02149   hi2s->TxCpltCallback(hi2s);
02150 #else
02151   HAL_I2S_TxCpltCallback(hi2s);
02152 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
02153 }
02154 
02155 /**
02156   * @brief  DMA I2S transmit process half complete callback
02157   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
02158   *         the configuration information for the specified DMA module.
02159   * @retval None
02160   */
02161 static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
02162 {
02163   /* Derogation MISRAC2012-Rule-11.5 */
02164   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
02165 
02166   /* Call user Tx half complete callback */
02167 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
02168   hi2s->TxHalfCpltCallback(hi2s);
02169 #else
02170   HAL_I2S_TxHalfCpltCallback(hi2s);
02171 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
02172 }
02173 
02174 /**
02175   * @brief  DMA I2S receive process complete callback
02176   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
02177   *         the configuration information for the specified DMA module.
02178   * @retval None
02179   */
02180 static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma)
02181 {
02182   /* Derogation MISRAC2012-Rule-11.5 */
02183   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
02184 
02185   /* if DMA is configured in DMA_NORMAL Mode */
02186   if (hdma->Init.Mode == DMA_NORMAL)
02187   {
02188     /* Disable Rx DMA Request */
02189     CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
02190     hi2s->RxXferCount = (uint16_t)0UL;
02191     hi2s->State = HAL_I2S_STATE_READY;
02192   }
02193   /* Call user Rx complete callback */
02194 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
02195   hi2s->RxCpltCallback(hi2s);
02196 #else
02197   HAL_I2S_RxCpltCallback(hi2s);
02198 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
02199 }
02200 
02201 /**
02202   * @brief  DMA I2S receive process half complete callback
02203   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
02204   *         the configuration information for the specified DMA module.
02205   * @retval None
02206   */
02207 static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
02208 {
02209   /* Derogation MISRAC2012-Rule-11.5 */
02210   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
02211 
02212   /* Call user Rx half complete callback */
02213 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
02214   hi2s->RxHalfCpltCallback(hi2s);
02215 #else
02216   HAL_I2S_RxHalfCpltCallback(hi2s);
02217 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
02218 }
02219 
02220 /**
02221   * @brief  DMA I2S transmit receive process complete callback
02222   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
02223   *               the configuration information for the specified DMA module.
02224   * @retval None
02225   */
02226 static void I2SEx_DMATxRxCplt(DMA_HandleTypeDef *hdma)
02227 {
02228   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
02229 
02230   /* Call user TxRx complete callback */
02231 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
02232   hi2s->TxRxCpltCallback(hi2s);
02233 #else
02234   HAL_I2SEx_TxRxCpltCallback(hi2s);
02235 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
02236 }
02237 
02238 /**
02239   * @brief  DMA I2S transmit receive process half complete callback
02240   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
02241   *               the configuration information for the specified DMA module.
02242   * @retval None
02243   */
02244 static void I2SEx_DMATxRxHalfCplt(DMA_HandleTypeDef *hdma)
02245 {
02246   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
02247 
02248   /* Call user TxRx Half complete callback */
02249 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
02250   hi2s->TxRxHalfCpltCallback(hi2s);
02251 #else
02252   HAL_I2SEx_TxRxHalfCpltCallback(hi2s);
02253 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
02254 }
02255 
02256 /**
02257   * @brief  DMA I2S communication error callback
02258   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
02259   *         the configuration information for the specified DMA module.
02260   * @retval None
02261   */
02262 static void I2S_DMAError(DMA_HandleTypeDef *hdma)
02263 {
02264   /* Derogation MISRAC2012-Rule-11.5 */
02265   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
02266 
02267   /* Disable Rx and Tx DMA Request */
02268   CLEAR_BIT(hi2s->Instance->CFG1, (SPI_CFG1_RXDMAEN | SPI_CFG1_TXDMAEN));
02269   hi2s->TxXferCount = (uint16_t) 0UL;
02270   hi2s->RxXferCount = (uint16_t) 0UL;
02271 
02272   hi2s->State = HAL_I2S_STATE_READY;
02273 
02274   /* Set the error code and execute error callback*/
02275   SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
02276   /* Call user error callback */
02277 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
02278   hi2s->ErrorCallback(hi2s);
02279 #else
02280   HAL_I2S_ErrorCallback(hi2s);
02281 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
02282 }
02283 
02284 /**
02285   * @brief  Manage the transmission 16-bit in Interrupt context
02286   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
02287   *         the configuration information for I2S module
02288   * @retval None
02289   */
02290 static void I2S_Transmit_16Bit_IT(I2S_HandleTypeDef *hi2s)
02291 {
02292   /* Transmit data */
02293 #if defined (__GNUC__)
02294   __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->TXDR));
02295 
02296   *ptxdr_16bits = *((uint16_t *)hi2s->pTxBuffPtr);
02297 #else
02298   *((__IO uint16_t *)&hi2s->Instance->TXDR) = *((uint16_t *)hi2s->pTxBuffPtr);
02299 #endif /* __GNUC__ */
02300   hi2s->pTxBuffPtr++;
02301   hi2s->TxXferCount--;
02302 
02303   if (hi2s->TxXferCount == 0UL)
02304   {
02305     /* Disable TXP and ERR interrupt */
02306     __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_ERR));
02307 
02308     if ((hi2s->Init.Mode == I2S_MODE_SLAVE_TX) || (hi2s->Init.Mode == I2S_MODE_MASTER_TX))
02309     {
02310       hi2s->State = HAL_I2S_STATE_READY;
02311     }
02312     /* Call user Tx complete callback */
02313 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
02314     hi2s->TxCpltCallback(hi2s);
02315 #else
02316     HAL_I2S_TxCpltCallback(hi2s);
02317 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
02318   }
02319 }
02320 
02321 /**
02322   * @brief  Manage the transmission 32-bit in Interrupt context
02323   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
02324   *         the configuration information for I2S module
02325   * @retval None
02326   */
02327 static void I2S_Transmit_32Bit_IT(I2S_HandleTypeDef *hi2s)
02328 {
02329   /* Transmit data */
02330   hi2s->Instance->TXDR = *((uint32_t *)hi2s->pTxBuffPtr);
02331   hi2s->pTxBuffPtr += 2;
02332   hi2s->TxXferCount--;
02333 
02334   if (hi2s->TxXferCount == 0UL)
02335   {
02336     /* Disable TXP and ERR interrupt */
02337     __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_ERR));
02338 
02339     if ((hi2s->Init.Mode == I2S_MODE_SLAVE_TX) || (hi2s->Init.Mode == I2S_MODE_MASTER_TX))
02340     {
02341       hi2s->State = HAL_I2S_STATE_READY;
02342     }
02343     /* Call user Tx complete callback */
02344 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
02345     hi2s->TxCpltCallback(hi2s);
02346 #else
02347     HAL_I2S_TxCpltCallback(hi2s);
02348 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
02349   }
02350 }
02351 
02352 /**
02353   * @brief  Manage the reception 16-bit in Interrupt context
02354   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
02355   *         the configuration information for I2S module
02356   * @retval None
02357   */
02358 static void I2S_Receive_16Bit_IT(I2S_HandleTypeDef *hi2s)
02359 {
02360   /* Receive data */
02361 #if defined (__GNUC__)
02362   __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->RXDR));
02363 
02364   *((uint16_t *)hi2s->pRxBuffPtr) = *prxdr_16bits;
02365 #else
02366   *((uint16_t *)hi2s->pRxBuffPtr) = *((__IO uint16_t *)&hi2s->Instance->RXDR);
02367 #endif /* __GNUC__ */
02368   hi2s->pRxBuffPtr++;
02369   hi2s->RxXferCount--;
02370 
02371   if (hi2s->RxXferCount == 0UL)
02372   {
02373     if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode))
02374     {
02375       /* Disable TXP, RXP, DXP, ERR interrupts */
02376       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_RXP | I2S_IT_DXP | I2S_IT_ERR));
02377     }
02378     else
02379     {
02380       /* Disable RXP and ERR interrupt */
02381       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXP | I2S_IT_ERR));
02382     }
02383 
02384     hi2s->State = HAL_I2S_STATE_READY;
02385     /* Call user Rx complete callback */
02386 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
02387     if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode))
02388     {
02389       hi2s->TxRxCpltCallback(hi2s);
02390     }
02391     else
02392     {
02393       hi2s->RxCpltCallback(hi2s);
02394     }
02395 #else
02396     if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode))
02397     {
02398       HAL_I2SEx_TxRxCpltCallback(hi2s);
02399     }
02400     else
02401     {
02402       HAL_I2S_RxCpltCallback(hi2s);
02403     }
02404 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
02405   }
02406 }
02407 
02408 /**
02409   * @brief  Manage the reception 32-bit in Interrupt context
02410   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
02411   *         the configuration information for I2S module
02412   * @retval None
02413   */
02414 static void I2S_Receive_32Bit_IT(I2S_HandleTypeDef *hi2s)
02415 {
02416   /* Receive data */
02417   *((uint32_t *)hi2s->pRxBuffPtr) = hi2s->Instance->RXDR;
02418   hi2s->pRxBuffPtr += 2;
02419   hi2s->RxXferCount--;
02420 
02421   if (hi2s->RxXferCount == 0UL)
02422   {
02423     if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode))
02424     {
02425       /* Disable TXP, RXP, DXP, ERR interrupts */
02426       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_RXP | I2S_IT_DXP | I2S_IT_ERR));
02427     }
02428     else
02429     {
02430       /* Disable RXP and ERR interrupt */
02431       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXP | I2S_IT_ERR));
02432     }
02433 
02434     hi2s->State = HAL_I2S_STATE_READY;
02435     /* Call user Rx complete callback */
02436 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
02437     if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode))
02438     {
02439       hi2s->TxRxCpltCallback(hi2s);
02440     }
02441     else
02442     {
02443       hi2s->RxCpltCallback(hi2s);
02444     }
02445 #else
02446     if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode))
02447     {
02448       HAL_I2SEx_TxRxCpltCallback(hi2s);
02449     }
02450     else
02451     {
02452       HAL_I2S_RxCpltCallback(hi2s);
02453     }
02454 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
02455   }
02456 }
02457 
02458 /**
02459   * @brief  This function handles I2S Communication Timeout.
02460   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
02461   *         the configuration information for I2S module
02462   * @param  Flag Flag checked
02463   * @param  State Value of the flag expected
02464   * @param  Timeout Duration of the timeout
02465   * @retval HAL status
02466   */
02467 static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State,
02468                                                        uint32_t Timeout)
02469 {
02470   uint32_t tickstart;
02471 
02472   /* Get tick */
02473   tickstart = HAL_GetTick();
02474 
02475   /* Wait until flag is set to status*/
02476   while (((__HAL_I2S_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State)
02477   {
02478     if (Timeout != HAL_MAX_DELAY)
02479     {
02480       if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0UL))
02481       {
02482         /* Set the I2S State ready */
02483         hi2s->State = HAL_I2S_STATE_READY;
02484 
02485         /* Process Unlocked */
02486         __HAL_UNLOCK(hi2s);
02487 
02488         return HAL_TIMEOUT;
02489       }
02490     }
02491   }
02492   return HAL_OK;
02493 }
02494 
02495 /**
02496   * @}
02497   */
02498 
02499 /**
02500   * @}
02501   */
02502 
02503 /**
02504   * @}
02505   */
02506 
02507 #endif /* HAL_I2S_MODULE_ENABLED */
02508