Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:08

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_i2s.c
0004   * @author  MCD Application Team
0005   * @brief   I2S HAL module driver.
0006   *          This file provides firmware functions to manage the following
0007   *          functionalities of the Integrated Interchip Sound (I2S) peripheral:
0008   *           + Initialization and de-initialization functions
0009   *           + IO operation functions
0010   *           + Peripheral State and Errors functions
0011   ******************************************************************************
0012   * @attention
0013   *
0014   * Copyright (c) 2017 STMicroelectronics.
0015   * All rights reserved.
0016   *
0017   * This software is licensed under terms that can be found in the LICENSE file
0018   * in the root directory of this software component.
0019   * If no LICENSE file comes with this software, it is provided AS-IS.
0020   *
0021   ******************************************************************************
0022   @verbatim
0023  ===============================================================================
0024                   ##### How to use this driver #####
0025  ===============================================================================
0026  [..]
0027     The I2S HAL driver can be used as follow:
0028 
0029     (#) Declare a I2S_HandleTypeDef handle structure.
0030     (#) Initialize the I2S low level resources by implement the HAL_I2S_MspInit() API:
0031         (##) Enable the SPIx interface clock.
0032         (##) I2S pins configuration:
0033             (+++) Enable the clock for the I2S GPIOs.
0034             (+++) Configure these I2S pins as alternate function pull-up.
0035         (##) NVIC configuration if you need to use interrupt process (HAL_I2S_Transmit_IT()
0036              and HAL_I2S_Receive_IT() APIs).
0037             (+++) Configure the I2Sx interrupt priority.
0038             (+++) Enable the NVIC I2S IRQ handle.
0039         (##) DMA Configuration if you need to use DMA process (HAL_I2S_Transmit_DMA()
0040              and HAL_I2S_Receive_DMA() APIs:
0041             (+++) Declare a DMA handle structure for the Tx/Rx Stream/Channel.
0042             (+++) Enable the DMAx interface clock.
0043             (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
0044             (+++) Configure the DMA Tx/Rx Stream/Channel.
0045             (+++) Associate the initialized DMA handle to the I2S DMA Tx/Rx handle.
0046             (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the
0047                   DMA Tx/Rx Stream/Channel.
0048 
0049    (#) Program the Mode, Standard, Data Format, MCLK Output, Audio frequency and Polarity
0050        using HAL_I2S_Init() function.
0051 
0052    -@- The specific I2S interrupts (Transmission complete interrupt,
0053        RXNE interrupt and Error Interrupts) will be managed using the macros
0054        __HAL_I2S_ENABLE_IT() and __HAL_I2S_DISABLE_IT() inside the transmit and receive process.
0055 
0056         (+@) External clock source is configured after setting correctly
0057              the define constant EXTERNAL_CLOCK_VALUE in the stm32h7xx_hal_conf.h file.
0058 
0059     (#) Three mode of operations are available within this driver :
0060 
0061    *** Polling mode IO operation ***
0062    =================================
0063    [..]
0064      (+) Send an amount of data in blocking mode using HAL_I2S_Transmit()
0065      (+) Receive an amount of data in blocking mode using HAL_I2S_Receive()
0066 
0067    *** Interrupt mode IO operation ***
0068    ===================================
0069    [..]
0070      (+) Send an amount of data in non blocking mode using HAL_I2S_Transmit_IT()
0071      (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
0072          add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
0073      (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
0074          add his own code by customization of function pointer HAL_I2S_TxCpltCallback
0075      (+) Receive an amount of data in non blocking mode using HAL_I2S_Receive_IT()
0076      (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
0077          add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
0078      (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
0079          add his own code by customization of function pointer HAL_I2S_RxCpltCallback
0080      (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
0081          add his own code by customization of function pointer HAL_I2S_ErrorCallback
0082 
0083    *** DMA mode IO operation ***
0084    ==============================
0085    [..]
0086      (+) Send an amount of data in non blocking mode (DMA) using HAL_I2S_Transmit_DMA()
0087      (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
0088          add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
0089      (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
0090          add his own code by customization of function pointer HAL_I2S_TxCpltCallback
0091      (+) Receive an amount of data in non blocking mode (DMA) using HAL_I2S_Receive_DMA()
0092      (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
0093          add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
0094      (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
0095          add his own code by customization of function pointer HAL_I2S_RxCpltCallback
0096      (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
0097          add his own code by customization of function pointer HAL_I2S_ErrorCallback
0098      (+) Pause the DMA Transfer using HAL_I2S_DMAPause()
0099      (+) Resume the DMA Transfer using HAL_I2S_DMAResume()
0100      (+) Stop the DMA Transfer using HAL_I2S_DMAStop()
0101 
0102    *** I2S HAL driver macros list ***
0103    ===================================
0104    [..]
0105      Below the list of most used macros in I2S HAL driver.
0106 
0107       (+) __HAL_I2S_ENABLE: Enable the specified SPI peripheral (in I2S mode)
0108       (+) __HAL_I2S_DISABLE: Disable the specified SPI peripheral (in I2S mode)
0109       (+) __HAL_I2S_ENABLE_IT : Enable the specified I2S interrupts
0110       (+) __HAL_I2S_DISABLE_IT : Disable the specified I2S interrupts
0111       (+) __HAL_I2S_GET_FLAG: Check whether the specified I2S flag is set or not
0112 
0113     [..]
0114       (@) You can refer to the I2S HAL driver header file for more useful macros
0115 
0116    *** I2S HAL driver macros list ***
0117    ===================================
0118    [..]
0119        Callback registration:
0120 
0121       (#) The compilation flag USE_HAL_I2S_REGISTER_CALLBACKS when set to 1UL
0122           allows the user to configure dynamically the driver callbacks.
0123           Use Functions HAL_I2S_RegisterCallback() to register an interrupt callback.
0124 
0125           Function HAL_I2S_RegisterCallback() allows to register following callbacks:
0126             (+) TxCpltCallback        : I2S Tx Completed callback
0127             (+) RxCpltCallback        : I2S Rx Completed callback
0128             (+) TxRxCpltCallback      : I2S TxRx Completed callback
0129             (+) TxHalfCpltCallback    : I2S Tx Half Completed callback
0130             (+) RxHalfCpltCallback    : I2S Rx Half Completed callback
0131             (+) TxRxHalfCpltCallback  : I2S TxRx Half Completed callback
0132             (+) ErrorCallback         : I2S Error callback
0133             (+) MspInitCallback       : I2S Msp Init callback
0134             (+) MspDeInitCallback     : I2S Msp DeInit callback
0135           This function takes as parameters the HAL peripheral handle, the Callback ID
0136           and a pointer to the user callback function.
0137 
0138 
0139       (#) Use function HAL_I2S_UnRegisterCallback to reset a callback to the default
0140           weak function.
0141           HAL_I2S_UnRegisterCallback takes as parameters the HAL peripheral handle,
0142           and the Callback ID.
0143           This function allows to reset following callbacks:
0144             (+) TxCpltCallback        : I2S Tx Completed callback
0145             (+) RxCpltCallback        : I2S Rx Completed callback
0146             (+) TxRxCpltCallback      : I2S TxRx Completed callback
0147             (+) TxHalfCpltCallback    : I2S Tx Half Completed callback
0148             (+) RxHalfCpltCallback    : I2S Rx Half Completed callback
0149             (+) TxRxHalfCpltCallback  : I2S TxRx Half Completed callback
0150             (+) ErrorCallback         : I2S Error callback
0151             (+) MspInitCallback       : I2S Msp Init callback
0152             (+) MspDeInitCallback     : I2S Msp DeInit callback
0153 
0154        By default, after the HAL_I2S_Init() and when the state is HAL_I2S_STATE_RESET
0155        all callbacks are set to the corresponding weak functions:
0156        examples HAL_I2S_MasterTxCpltCallback(), HAL_I2S_MasterRxCpltCallback().
0157        Exception done for MspInit and MspDeInit functions that are
0158        reset to the legacy weak functions in the HAL_I2S_Init()/ HAL_I2S_DeInit() only when
0159        these callbacks are null (not registered beforehand).
0160        If MspInit or MspDeInit are not null, the HAL_I2S_Init()/ HAL_I2S_DeInit()
0161        keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
0162 
0163        Callbacks can be registered/unregistered in HAL_I2S_STATE_READY state only.
0164        Exception done MspInit/MspDeInit functions that can be registered/unregistered
0165        in HAL_I2S_STATE_READY or HAL_I2S_STATE_RESET state,
0166        thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
0167        Then, the user first registers the MspInit/MspDeInit user callbacks
0168        using HAL_I2S_RegisterCallback() before calling HAL_I2S_DeInit()
0169        or HAL_I2S_Init() function.
0170 
0171        When The compilation define USE_HAL_I2S_REGISTER_CALLBACKS is set to 0 or
0172        not defined, the callback registering feature is not available
0173        and weak callbacks are used.
0174 
0175 
0176   @endverbatim
0177   */
0178 
0179 /* Includes ------------------------------------------------------------------*/
0180 #include "stm32h7xx_hal.h"
0181 
0182 #ifdef HAL_I2S_MODULE_ENABLED
0183 
0184 /** @addtogroup STM32H7xx_HAL_Driver
0185   * @{
0186   */
0187 
0188 /** @defgroup I2S I2S
0189   * @ingroup RTEMSBSPsARMSTM32H7
0190   * @brief I2S HAL module driver
0191   * @{
0192   */
0193 
0194 /* Private typedef -----------------------------------------------------------*/
0195 /* Private define ------------------------------------------------------------*/
0196 /** @defgroup I2S_Private_Define I2S Private Define
0197   * @ingroup RTEMSBSPsARMSTM32H7
0198   * @{
0199   */
0200 #define I2S_TIMEOUT 0xFFFFUL
0201 /**
0202   * @}
0203   */
0204 
0205 /* Private macro -------------------------------------------------------------*/
0206 /* Private variables ---------------------------------------------------------*/
0207 /* Private function prototypes -----------------------------------------------*/
0208 /** @defgroup I2S_Private_Functions I2S Private Functions
0209   * @ingroup RTEMSBSPsARMSTM32H7
0210   * @{
0211   */
0212 static void               I2S_DMATxCplt(DMA_HandleTypeDef *hdma);
0213 static void               I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
0214 static void               I2S_DMARxCplt(DMA_HandleTypeDef *hdma);
0215 static void               I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
0216 static void               I2SEx_DMATxRxCplt(DMA_HandleTypeDef *hdma);
0217 static void               I2SEx_DMATxRxHalfCplt(DMA_HandleTypeDef *hdma);
0218 static void               I2S_DMAError(DMA_HandleTypeDef *hdma);
0219 static void               I2S_Transmit_16Bit_IT(I2S_HandleTypeDef *hi2s);
0220 static void               I2S_Transmit_32Bit_IT(I2S_HandleTypeDef *hi2s);
0221 static void               I2S_Receive_16Bit_IT(I2S_HandleTypeDef *hi2s);
0222 static void               I2S_Receive_32Bit_IT(I2S_HandleTypeDef *hi2s);
0223 static HAL_StatusTypeDef  I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State,
0224                                                         uint32_t Tickstart, uint32_t Timeout);
0225 /**
0226   * @}
0227   */
0228 
0229 /* Exported functions ---------------------------------------------------------*/
0230 
0231 /** @defgroup I2S_Exported_Functions I2S Exported Functions
0232   * @ingroup RTEMSBSPsARMSTM32H7
0233   * @{
0234   */
0235 
0236 /** @defgroup  I2S_Exported_Functions_Group1 Initialization and de-initialization functions
0237   * @ingroup RTEMSBSPsARMSTM32H7
0238   *  @brief    Initialization and Configuration functions
0239   *
0240 @verbatim
0241  ===============================================================================
0242               ##### Initialization and de-initialization functions #####
0243  ===============================================================================
0244     [..]  This subsection provides a set of functions allowing to initialize and
0245           de-initialize the I2Sx peripheral in simplex mode:
0246 
0247       (+) User must Implement HAL_I2S_MspInit() function in which he configures
0248           all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
0249 
0250       (+) Call the function HAL_I2S_Init() to configure the selected device with
0251           the selected configuration:
0252         (++) Mode
0253         (++) Standard
0254         (++) Data Format
0255         (++) MCLK Output
0256         (++) Audio frequency
0257         (++) Polarity
0258 
0259      (+) Call the function HAL_I2S_DeInit() to restore the default configuration
0260           of the selected I2Sx peripheral.
0261   @endverbatim
0262   * @{
0263   */
0264 
0265 /**
0266   * @brief  Initializes the I2S according to the specified parameters
0267   *         in the I2S_InitTypeDef and create the associated handle.
0268   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
0269   *         the configuration information for I2S module
0270   * @retval HAL status
0271   */
0272 HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s)
0273 {
0274   uint32_t i2sdiv;
0275   uint32_t i2sodd;
0276   uint32_t packetlength;
0277   uint32_t tmp;
0278   uint32_t i2sclk;
0279   uint32_t ispcm;
0280 
0281   /* Check the I2S handle allocation */
0282   if (hi2s == NULL)
0283   {
0284     return HAL_ERROR;
0285   }
0286 
0287   /* Check the I2S parameters */
0288   assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
0289   assert_param(IS_I2S_MODE(hi2s->Init.Mode));
0290   assert_param(IS_I2S_STANDARD(hi2s->Init.Standard));
0291   assert_param(IS_I2S_DATA_FORMAT(hi2s->Init.DataFormat));
0292   assert_param(IS_I2S_MCLK_OUTPUT(hi2s->Init.MCLKOutput));
0293   assert_param(IS_I2S_AUDIO_FREQ(hi2s->Init.AudioFreq));
0294   assert_param(IS_I2S_CPOL(hi2s->Init.CPOL));
0295   assert_param(IS_I2S_FIRST_BIT(hi2s->Init.FirstBit));
0296   assert_param(IS_I2S_WS_INVERSION(hi2s->Init.WSInversion));
0297   assert_param(IS_I2S_DATA_24BIT_ALIGNMENT(hi2s->Init.Data24BitAlignment));
0298   assert_param(IS_I2S_MASTER_KEEP_IO_STATE(hi2s->Init.MasterKeepIOState));
0299 
0300   if (hi2s->State == HAL_I2S_STATE_RESET)
0301   {
0302     /* Allocate lock resource and initialize it */
0303     hi2s->Lock = HAL_UNLOCKED;
0304 
0305 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
0306     /* Init the I2S Callback settings */
0307     hi2s->TxCpltCallback       = HAL_I2S_TxCpltCallback;          /* Legacy weak TxCpltCallback       */
0308     hi2s->RxCpltCallback       = HAL_I2S_RxCpltCallback;          /* Legacy weak RxCpltCallback       */
0309     hi2s->TxRxCpltCallback     = HAL_I2SEx_TxRxCpltCallback;      /* Legacy weak TxRxCpltCallback     */
0310     hi2s->TxHalfCpltCallback   = HAL_I2S_TxHalfCpltCallback;      /* Legacy weak TxHalfCpltCallback   */
0311     hi2s->RxHalfCpltCallback   = HAL_I2S_RxHalfCpltCallback;      /* Legacy weak RxHalfCpltCallback   */
0312     hi2s->TxRxHalfCpltCallback = HAL_I2SEx_TxRxHalfCpltCallback;  /* Legacy weak TxRxHalfCpltCallback */
0313     hi2s->ErrorCallback        = HAL_I2S_ErrorCallback;           /* Legacy weak ErrorCallback        */
0314 
0315     if (hi2s->MspInitCallback == NULL)
0316     {
0317       hi2s->MspInitCallback = HAL_I2S_MspInit; /* Legacy weak MspInit  */
0318     }
0319 
0320     /* Init the low level hardware : GPIO, CLOCK, NVIC... */
0321     hi2s->MspInitCallback(hi2s);
0322 #else
0323     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
0324     HAL_I2S_MspInit(hi2s);
0325 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
0326   }
0327 
0328   hi2s->State = HAL_I2S_STATE_BUSY;
0329 
0330   /* Disable the selected I2S peripheral */
0331   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) == SPI_CR1_SPE)
0332   {
0333     /* Disable I2S peripheral */
0334     __HAL_I2S_DISABLE(hi2s);
0335   }
0336 
0337   /* Clear I2S configuration register */
0338   CLEAR_REG(hi2s->Instance->I2SCFGR);
0339 
0340   if (IS_I2S_MASTER(hi2s->Init.Mode))
0341   {
0342     /*------------------------- I2SDIV and ODD Calculation ---------------------*/
0343     /* If the requested audio frequency is not the default, compute the prescaler */
0344     if (hi2s->Init.AudioFreq != I2S_AUDIOFREQ_DEFAULT)
0345     {
0346       /* Check the frame length (For the Prescaler computing) ********************/
0347       if (hi2s->Init.DataFormat != I2S_DATAFORMAT_16B)
0348       {
0349         /* Channel length is 32 bits */
0350         packetlength = 2UL;
0351       }
0352       else
0353       {
0354         /* Channel length is 16 bits */
0355         packetlength = 1UL;
0356       }
0357 
0358       /* Check if PCM standard is used */
0359       if ((hi2s->Init.Standard == I2S_STANDARD_PCM_SHORT) ||
0360           (hi2s->Init.Standard == I2S_STANDARD_PCM_LONG))
0361       {
0362         ispcm = 1UL;
0363       }
0364       else
0365       {
0366         ispcm = 0UL;
0367       }
0368 
0369       /* Get the source clock value: based on System Clock value */
0370 #if defined (SPI_SPI6I2S_SUPPORT)
0371       if (hi2s->Instance == SPI6)
0372       {
0373         /* SPI6 source clock */
0374         i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI6);
0375       }
0376       else
0377       {
0378         /* SPI1,SPI2 and SPI3 share the same source clock */
0379         i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI123);
0380       }
0381 #else
0382       /* SPI1,SPI2 and SPI3 share the same source clock */
0383       i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SPI123);
0384 #endif  /* SPI_SPI6I2S_SUPPORT */
0385 
0386       /* Compute the Real divider depending on the MCLK output state, with a floating point */
0387       if (hi2s->Init.MCLKOutput == I2S_MCLKOUTPUT_ENABLE)
0388       {
0389         /* MCLK output is enabled */
0390         tmp = (uint32_t)((((i2sclk / (256UL >> ispcm)) * 10UL) / hi2s->Init.AudioFreq) + 5UL);
0391       }
0392       else
0393       {
0394         /* MCLK output is disabled */
0395         tmp = (uint32_t)((((i2sclk / ((32UL >> ispcm) * packetlength)) * 10UL) / hi2s->Init.AudioFreq) + 5UL);
0396       }
0397 
0398       /* Remove the flatting point */
0399       tmp = tmp / 10UL;
0400 
0401       /* Check the parity of the divider */
0402       i2sodd = (uint32_t)(tmp & (uint32_t)1UL);
0403 
0404       /* Compute the i2sdiv prescaler */
0405       i2sdiv = (uint32_t)((tmp - i2sodd) / 2UL);
0406     }
0407     else
0408     {
0409       /* Set the default values */
0410       i2sdiv = 2UL;
0411       i2sodd = 0UL;
0412     }
0413 
0414     /* Test if the obtain values are forbidden or out of range */
0415     if (((i2sodd == 1UL) && (i2sdiv == 1UL)) || (i2sdiv > 0xFFUL))
0416     {
0417       /* Set the error code */
0418       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_PRESCALER);
0419       return  HAL_ERROR;
0420     }
0421 
0422     /* Force i2smod to 1 just to be sure that (2xi2sdiv + i2sodd) is always higher than 0 */
0423     if (i2sdiv == 0UL)
0424     {
0425       i2sodd = 1UL;
0426     }
0427 
0428     MODIFY_REG(hi2s->Instance->I2SCFGR, (SPI_I2SCFGR_I2SDIV                 | SPI_I2SCFGR_ODD),
0429                ((i2sdiv << SPI_I2SCFGR_I2SDIV_Pos) | (i2sodd << SPI_I2SCFGR_ODD_Pos)));
0430   }
0431 
0432   /*-------------------------- I2Sx I2SCFGR Configuration --------------------*/
0433   /* Configure I2SMOD, I2SCFG, I2SSTD, PCMSYNC, DATLEN ,CHLEN ,CKPOL, WSINV, DATAFMT, I2SDIV, ODD and MCKOE bits bits */
0434   /* And configure the I2S with the I2S_InitStruct values */
0435   MODIFY_REG(hi2s->Instance->I2SCFGR, (SPI_I2SCFGR_I2SMOD   | SPI_I2SCFGR_I2SCFG     | \
0436                                        SPI_I2SCFGR_I2SSTD   | SPI_I2SCFGR_PCMSYNC    | \
0437                                        SPI_I2SCFGR_DATLEN   | SPI_I2SCFGR_CHLEN      | \
0438                                        SPI_I2SCFGR_CKPOL    | SPI_I2SCFGR_WSINV      | \
0439                                        SPI_I2SCFGR_DATFMT   | SPI_I2SCFGR_MCKOE),
0440              (SPI_I2SCFGR_I2SMOD   | hi2s->Init.Mode        | \
0441               hi2s->Init.Standard  | hi2s->Init.DataFormat  | \
0442               hi2s->Init.CPOL      | hi2s->Init.WSInversion | \
0443               hi2s->Init.Data24BitAlignment | hi2s->Init.MCLKOutput));
0444   /*Clear status register*/
0445   WRITE_REG(hi2s->Instance->IFCR, 0x0FF8);
0446 
0447   /*---------------------------- I2Sx CFG2 Configuration ----------------------*/
0448 
0449   /* Unlock the AF configuration to configure CFG2 register*/
0450   CLEAR_BIT(hi2s->Instance->CR1, SPI_CR1_IOLOCK);
0451 
0452   MODIFY_REG(hi2s->Instance->CFG2, SPI_CFG2_LSBFRST, hi2s->Init.FirstBit);
0453 
0454   /* Insure that AFCNTR is managed only by Master */
0455   if (IS_I2S_MASTER(hi2s->Init.Mode))
0456   {
0457     /* Alternate function GPIOs control */
0458     MODIFY_REG(hi2s->Instance->CFG2, SPI_CFG2_AFCNTR, (hi2s->Init.MasterKeepIOState));
0459   }
0460 
0461   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
0462   hi2s->State     = HAL_I2S_STATE_READY;
0463 
0464   return HAL_OK;
0465 }
0466 
0467 /**
0468   * @brief DeInitializes the I2S peripheral
0469   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
0470   *         the configuration information for I2S module
0471   * @retval HAL status
0472   */
0473 HAL_StatusTypeDef HAL_I2S_DeInit(I2S_HandleTypeDef *hi2s)
0474 {
0475   /* Check the I2S handle allocation */
0476   if (hi2s == NULL)
0477   {
0478     return HAL_ERROR;
0479   }
0480 
0481   /* Check the parameters */
0482   assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
0483 
0484   hi2s->State = HAL_I2S_STATE_BUSY;
0485 
0486   /* Disable the I2S Peripheral Clock */
0487   __HAL_I2S_DISABLE(hi2s);
0488 
0489 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
0490   if (hi2s->MspDeInitCallback == NULL)
0491   {
0492     hi2s->MspDeInitCallback = HAL_I2S_MspDeInit; /* Legacy weak MspDeInit  */
0493   }
0494 
0495   /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
0496   hi2s->MspDeInitCallback(hi2s);
0497 #else
0498   /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
0499   HAL_I2S_MspDeInit(hi2s);
0500 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
0501 
0502   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
0503   hi2s->State     = HAL_I2S_STATE_RESET;
0504 
0505   /* Release Lock */
0506   __HAL_UNLOCK(hi2s);
0507 
0508   return HAL_OK;
0509 }
0510 
0511 /**
0512   * @brief I2S MSP Init
0513   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
0514   *         the configuration information for I2S module
0515   * @retval None
0516   */
0517 __weak void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s)
0518 {
0519   /* Prevent unused argument(s) compilation warning */
0520   UNUSED(hi2s);
0521 
0522   /* NOTE : This function Should not be modified, when the callback is needed,
0523             the HAL_I2S_MspInit could be implemented in the user file
0524    */
0525 }
0526 
0527 /**
0528   * @brief I2S MSP DeInit
0529   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
0530   *         the configuration information for I2S module
0531   * @retval None
0532   */
0533 __weak void HAL_I2S_MspDeInit(I2S_HandleTypeDef *hi2s)
0534 {
0535   /* Prevent unused argument(s) compilation warning */
0536   UNUSED(hi2s);
0537 
0538   /* NOTE : This function Should not be modified, when the callback is needed,
0539             the HAL_I2S_MspDeInit could be implemented in the user file
0540    */
0541 }
0542 
0543 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
0544 /**
0545   * @brief  Register a User I2S Callback
0546   *         To be used instead of the weak predefined callback
0547   * @param  hi2s Pointer to a I2S_HandleTypeDef structure that contains
0548   *                the configuration information for the specified I2S.
0549   * @param  CallbackID ID of the callback to be registered
0550   * @param  pCallback pointer to the Callback function
0551   * @note   The HAL_I2S_RegisterCallback() may be called before HAL_I2S_Init() in HAL_I2S_STATE_RESET
0552   *         to register callbacks for HAL_I2S_MSPINIT_CB_ID and HAL_I2S_MSPDEINIT_CB_ID
0553   * @retval HAL status
0554   */
0555 HAL_StatusTypeDef HAL_I2S_RegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID,
0556                                            pI2S_CallbackTypeDef pCallback)
0557 {
0558   HAL_StatusTypeDef status = HAL_OK;
0559 
0560   if (pCallback == NULL)
0561   {
0562     /* Update the error code */
0563     hi2s->ErrorCode |= HAL_I2S_ERROR_INVALID_CALLBACK;
0564 
0565     return HAL_ERROR;
0566   }
0567 
0568   if (HAL_I2S_STATE_READY == hi2s->State)
0569   {
0570     switch (CallbackID)
0571     {
0572       case HAL_I2S_TX_COMPLETE_CB_ID :
0573         hi2s->TxCpltCallback = pCallback;
0574         break;
0575 
0576       case HAL_I2S_RX_COMPLETE_CB_ID :
0577         hi2s->RxCpltCallback = pCallback;
0578         break;
0579 
0580       case HAL_I2S_TX_RX_COMPLETE_CB_ID :
0581         hi2s->TxRxCpltCallback = pCallback;
0582         break;
0583 
0584       case HAL_I2S_TX_HALF_COMPLETE_CB_ID :
0585         hi2s->TxHalfCpltCallback = pCallback;
0586         break;
0587 
0588       case HAL_I2S_RX_HALF_COMPLETE_CB_ID :
0589         hi2s->RxHalfCpltCallback = pCallback;
0590         break;
0591 
0592 
0593       case HAL_I2S_TX_RX_HALF_COMPLETE_CB_ID :
0594         hi2s->TxRxHalfCpltCallback = pCallback;
0595         break;
0596 
0597       case HAL_I2S_ERROR_CB_ID :
0598         hi2s->ErrorCallback = pCallback;
0599         break;
0600 
0601       case HAL_I2S_MSPINIT_CB_ID :
0602         hi2s->MspInitCallback = pCallback;
0603         break;
0604 
0605       case HAL_I2S_MSPDEINIT_CB_ID :
0606         hi2s->MspDeInitCallback = pCallback;
0607         break;
0608 
0609       default :
0610         /* Update the error code */
0611         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
0612 
0613         /* Return error status */
0614         status =  HAL_ERROR;
0615         break;
0616     }
0617   }
0618   else if (HAL_I2S_STATE_RESET == hi2s->State)
0619   {
0620     switch (CallbackID)
0621     {
0622       case HAL_I2S_MSPINIT_CB_ID :
0623         hi2s->MspInitCallback = pCallback;
0624         break;
0625 
0626       case HAL_I2S_MSPDEINIT_CB_ID :
0627         hi2s->MspDeInitCallback = pCallback;
0628         break;
0629 
0630       default :
0631         /* Update the error code */
0632         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
0633 
0634         /* Return error status */
0635         status =  HAL_ERROR;
0636         break;
0637     }
0638   }
0639   else
0640   {
0641     /* Update the error code */
0642     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
0643 
0644     /* Return error status */
0645     status =  HAL_ERROR;
0646   }
0647 
0648   return status;
0649 }
0650 
0651 /**
0652   * @brief  Unregister an I2S Callback
0653   *         I2S callback is redirected to the weak predefined callback
0654   * @param  hi2s Pointer to a I2S_HandleTypeDef structure that contains
0655   *                the configuration information for the specified I2S.
0656   * @param  CallbackID ID of the callback to be unregistered
0657   * @note   The HAL_I2S_UnRegisterCallback() may be called before HAL_I2S_Init() in HAL_I2S_STATE_RESET
0658   *         to un-register callbacks for HAL_I2S_MSPINIT_CB_ID and HAL_I2S_MSPDEINIT_CB_ID
0659   * @retval HAL status
0660   */
0661 HAL_StatusTypeDef HAL_I2S_UnRegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID)
0662 {
0663   HAL_StatusTypeDef status = HAL_OK;
0664 
0665   if (HAL_I2S_STATE_READY == hi2s->State)
0666   {
0667     switch (CallbackID)
0668     {
0669       case HAL_I2S_TX_COMPLETE_CB_ID :
0670         hi2s->TxCpltCallback = HAL_I2S_TxCpltCallback;                /* Legacy weak TxCpltCallback       */
0671         break;
0672 
0673       case HAL_I2S_RX_COMPLETE_CB_ID :
0674         hi2s->RxCpltCallback = HAL_I2S_RxCpltCallback;                /* Legacy weak RxCpltCallback       */
0675         break;
0676 
0677       case HAL_I2S_TX_RX_COMPLETE_CB_ID :
0678         hi2s->TxRxCpltCallback = HAL_I2SEx_TxRxCpltCallback;          /* Legacy weak TxRxCpltCallback     */
0679         break;
0680 
0681       case HAL_I2S_TX_HALF_COMPLETE_CB_ID :
0682         hi2s->TxHalfCpltCallback = HAL_I2S_TxHalfCpltCallback;        /* Legacy weak TxHalfCpltCallback   */
0683         break;
0684 
0685       case HAL_I2S_RX_HALF_COMPLETE_CB_ID :
0686         hi2s->RxHalfCpltCallback = HAL_I2S_RxHalfCpltCallback;        /* Legacy weak RxHalfCpltCallback   */
0687         break;
0688 
0689       case HAL_I2S_TX_RX_HALF_COMPLETE_CB_ID :
0690         hi2s->TxRxHalfCpltCallback = HAL_I2SEx_TxRxHalfCpltCallback;  /* Legacy weak TxRxHalfCpltCallback */
0691         break;
0692 
0693       case HAL_I2S_ERROR_CB_ID :
0694         hi2s->ErrorCallback = HAL_I2S_ErrorCallback;                  /* Legacy weak ErrorCallback        */
0695         break;
0696 
0697       case HAL_I2S_MSPINIT_CB_ID :
0698         hi2s->MspInitCallback = HAL_I2S_MspInit;                      /* Legacy weak MspInit              */
0699         break;
0700 
0701       case HAL_I2S_MSPDEINIT_CB_ID :
0702         hi2s->MspDeInitCallback = HAL_I2S_MspDeInit;                  /* Legacy weak MspDeInit            */
0703         break;
0704 
0705       default :
0706         /* Update the error code */
0707         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
0708 
0709         /* Return error status */
0710         status =  HAL_ERROR;
0711         break;
0712     }
0713   }
0714   else if (HAL_I2S_STATE_RESET == hi2s->State)
0715   {
0716     switch (CallbackID)
0717     {
0718       case HAL_I2S_MSPINIT_CB_ID :
0719         hi2s->MspInitCallback = HAL_I2S_MspInit;                      /* Legacy weak MspInit              */
0720         break;
0721 
0722       case HAL_I2S_MSPDEINIT_CB_ID :
0723         hi2s->MspDeInitCallback = HAL_I2S_MspDeInit;                  /* Legacy weak MspDeInit            */
0724         break;
0725 
0726       default :
0727         /* Update the error code */
0728         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
0729 
0730         /* Return error status */
0731         status =  HAL_ERROR;
0732         break;
0733     }
0734   }
0735   else
0736   {
0737     /* Update the error code */
0738     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
0739 
0740     /* Return error status */
0741     status =  HAL_ERROR;
0742   }
0743 
0744   return status;
0745 }
0746 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
0747 /**
0748   * @}
0749   */
0750 
0751 /** @defgroup I2S_Exported_Functions_Group2 IO operation functions
0752   * @ingroup RTEMSBSPsARMSTM32H7
0753   *  @brief Data transfers functions
0754   *
0755 @verbatim
0756  ===============================================================================
0757                       ##### IO operation functions #####
0758  ===============================================================================
0759     [..]
0760     This subsection provides a set of functions allowing to manage the I2S data
0761     transfers.
0762 
0763     (#) There are two modes of transfer:
0764        (++) Blocking mode : The communication is performed in the polling mode.
0765             The status of all data processing is returned by the same function
0766             after finishing transfer.
0767        (++) No-Blocking mode : The communication is performed using Interrupts
0768             or DMA. These functions return the status of the transfer startup.
0769             The end of the data processing will be indicated through the
0770             dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when
0771             using DMA mode.
0772 
0773     (#) Blocking mode functions are :
0774         (++) HAL_I2S_Transmit()
0775         (++) HAL_I2S_Receive()
0776         (++) HAL_I2SEx_TransmitReceive()
0777 
0778     (#) No-Blocking mode functions with Interrupt are :
0779         (++) HAL_I2S_Transmit_IT()
0780         (++) HAL_I2S_Receive_IT()
0781         (++) HAL_I2SEx_TransmitReceive_IT()
0782 
0783     (#) No-Blocking mode functions with DMA are :
0784         (++) HAL_I2S_Transmit_DMA()
0785         (++) HAL_I2S_Receive_DMA()
0786         (++) HAL_I2SEx_TransmitReceive_DMA()
0787 
0788     (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
0789         (++) HAL_I2S_TxCpltCallback()
0790         (++) HAL_I2S_RxCpltCallback()
0791         (++) HAL_I2SEx_TxRxCpltCallback()
0792         (++) HAL_I2S_ErrorCallback()
0793 
0794 @endverbatim
0795   * @{
0796   */
0797 
0798 /**
0799   * @brief  Transmit an amount of data in blocking mode
0800   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
0801   *         the configuration information for I2S module
0802   * @param  pData a 16-bit pointer to data buffer.
0803   * @param  Size number of data sample to be sent:
0804   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
0805   *         configuration phase, the Size parameter means the number of 16-bit data length
0806   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
0807   *         the Size parameter means the number of 16-bit data length.
0808   * @param  Timeout Timeout duration
0809   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
0810   *         between Master and Slave(example: audio streaming).
0811   * @retval HAL status
0812   */
0813 HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, const uint16_t *pData, uint16_t Size, uint32_t Timeout)
0814 {
0815 #if defined (__GNUC__)
0816   __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->TXDR));
0817 #endif /* __GNUC__ */
0818   uint32_t tickstart;
0819 
0820   if ((pData == NULL) || (Size == 0UL))
0821   {
0822     return  HAL_ERROR;
0823   }
0824 
0825   if (hi2s->State != HAL_I2S_STATE_READY)
0826   {
0827     return HAL_BUSY;
0828   }
0829 
0830   /* Process Locked */
0831   __HAL_LOCK(hi2s);
0832 
0833   /* Init tickstart for timeout management*/
0834   tickstart = HAL_GetTick();
0835 
0836   /* Set state and reset error code */
0837   hi2s->State       = HAL_I2S_STATE_BUSY_TX;
0838   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
0839   hi2s->pTxBuffPtr  = (const uint16_t *)pData;
0840   hi2s->TxXferSize  = Size;
0841   hi2s->TxXferCount = Size;
0842 
0843   /* Initialize fields not used in handle to zero */
0844   hi2s->pRxBuffPtr  = NULL;
0845   hi2s->RxXferSize  = (uint16_t) 0UL;
0846   hi2s->RxXferCount = (uint16_t) 0UL;
0847 
0848   /* Check if the I2S is already enabled */
0849   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
0850   {
0851     /* Enable I2S peripheral */
0852     __HAL_I2S_ENABLE(hi2s);
0853   }
0854 
0855   /* Start the transfer */
0856   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
0857 
0858 
0859   /* Wait until TXP flag is set */
0860   if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXP, SET, tickstart, Timeout) != HAL_OK)
0861   {
0862     /* Set the error code */
0863     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
0864     hi2s->State = HAL_I2S_STATE_READY;
0865     __HAL_UNLOCK(hi2s);
0866     return HAL_TIMEOUT;
0867   }
0868 
0869   while (hi2s->TxXferCount > 0UL)
0870   {
0871     if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
0872     {
0873       /* Transmit data in 32 Bit mode */
0874       hi2s->Instance->TXDR = *((const uint32_t *)hi2s->pTxBuffPtr);
0875       hi2s->pTxBuffPtr += 2;
0876       hi2s->TxXferCount--;
0877     }
0878     else
0879     {
0880       /* Transmit data in 16 Bit mode */
0881 #if defined (__GNUC__)
0882       *ptxdr_16bits = *((const uint16_t *)hi2s->pTxBuffPtr);
0883 #else
0884       *((__IO uint16_t *)&hi2s->Instance->TXDR) = *((const uint16_t *)hi2s->pTxBuffPtr);
0885 #endif /* __GNUC__ */
0886 
0887       hi2s->pTxBuffPtr++;
0888       hi2s->TxXferCount--;
0889     }
0890 
0891     /* Wait until TXP flag is set */
0892     if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXP, SET, tickstart, Timeout) != HAL_OK)
0893     {
0894       /* Set the error code */
0895       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
0896       hi2s->State = HAL_I2S_STATE_READY;
0897       __HAL_UNLOCK(hi2s);
0898       return HAL_TIMEOUT;
0899     }
0900 
0901     /* Check if an underrun occurs */
0902     if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET)
0903     {
0904       /* Clear underrun flag */
0905       __HAL_I2S_CLEAR_UDRFLAG(hi2s);
0906 
0907       /* Set the error code */
0908       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
0909     }
0910   }
0911 
0912   hi2s->State = HAL_I2S_STATE_READY;
0913   __HAL_UNLOCK(hi2s);
0914   return HAL_OK;
0915 }
0916 
0917 /**
0918   * @brief  Receive an amount of data in blocking mode
0919   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
0920   *         the configuration information for I2S module
0921   * @param  pData a 16-bit pointer to data buffer.
0922   * @param  Size number of data sample to be sent:
0923   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
0924   *         configuration phase, the Size parameter means the number of 16-bit data length
0925   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
0926   *         the Size parameter means the number of 16-bit data length.
0927   * @param  Timeout Timeout duration
0928   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
0929   *         between Master and Slave(example: audio streaming).
0930   * @note   In I2S Master Receiver mode, just after enabling the peripheral the clock will be generate
0931   *         in continuous way and as the I2S is not disabled at the end of the I2S transaction.
0932   * @retval HAL status
0933   */
0934 HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
0935 {
0936 #if defined (__GNUC__)
0937   __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->RXDR));
0938 #endif /* __GNUC__ */
0939   uint32_t tickstart;
0940 
0941   if ((pData == NULL) || (Size == 0UL))
0942   {
0943     return  HAL_ERROR;
0944   }
0945 
0946   if (hi2s->State != HAL_I2S_STATE_READY)
0947   {
0948     return HAL_BUSY;
0949   }
0950 
0951   /* Process Locked */
0952   __HAL_LOCK(hi2s);
0953 
0954   /* Init tickstart for timeout management*/
0955   tickstart = HAL_GetTick();
0956 
0957   /* Set state and reset error code */
0958   hi2s->State       = HAL_I2S_STATE_BUSY_RX;
0959   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
0960   hi2s->pRxBuffPtr  = pData;
0961   hi2s->RxXferSize  = Size;
0962   hi2s->RxXferCount = Size;
0963 
0964   /* Initialize fields not used in handle to zero */
0965   hi2s->pTxBuffPtr  = NULL;
0966   hi2s->TxXferSize  = (uint16_t) 0UL;
0967   hi2s->TxXferCount = (uint16_t) 0UL;
0968 
0969   /* Check if the I2S is already enabled */
0970   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
0971   {
0972     /* Enable I2S peripheral */
0973     __HAL_I2S_ENABLE(hi2s);
0974   }
0975 
0976   /* Start the transfer */
0977   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
0978 
0979   /* Receive data */
0980   while (hi2s->RxXferCount > 0UL)
0981   {
0982     /* Wait until RXP flag is set */
0983     if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXP, SET, tickstart, Timeout) != HAL_OK)
0984     {
0985       /* Set the error code */
0986       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
0987       hi2s->State = HAL_I2S_STATE_READY;
0988       __HAL_UNLOCK(hi2s);
0989       return HAL_TIMEOUT;
0990     }
0991 
0992     if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
0993     {
0994       /* Receive data in 32 Bit mode */
0995       *((uint32_t *)hi2s->pRxBuffPtr) = hi2s->Instance->RXDR;
0996       hi2s->pRxBuffPtr += 2;
0997       hi2s->RxXferCount--;
0998     }
0999     else
1000     {
1001       /* Receive data in 16 Bit mode */
1002 #if defined (__GNUC__)
1003       *((uint16_t *)hi2s->pRxBuffPtr) = *prxdr_16bits;
1004 #else
1005       *((uint16_t *)hi2s->pRxBuffPtr) = *((__IO uint16_t *)&hi2s->Instance->RXDR);
1006 #endif /* __GNUC__ */
1007       hi2s->pRxBuffPtr++;
1008       hi2s->RxXferCount--;
1009     }
1010 
1011     /* Check if an overrun occurs */
1012     if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
1013     {
1014       /* Clear overrun flag */
1015       __HAL_I2S_CLEAR_OVRFLAG(hi2s);
1016 
1017       /* Set the error code */
1018       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
1019     }
1020   }
1021 
1022   hi2s->State = HAL_I2S_STATE_READY;
1023   __HAL_UNLOCK(hi2s);
1024   return HAL_OK;
1025 }
1026 
1027 /**
1028   * @brief  Full-Duplex Transmit/Receive data in blocking mode.
1029   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1030   *         the configuration information for I2S module
1031   * @param  pTxData a 16-bit pointer to the Transmit data buffer.
1032   * @param  pRxData a 16-bit pointer to the Receive data buffer.
1033   * @param  Size number of data sample to be sent:
1034   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1035   *         configuration phase, the Size parameter means the number of 16-bit data length
1036   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1037   *         the Size parameter means the number of 16-bit data length.
1038   * @param  Timeout Timeout duration
1039   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1040   *         between Master and Slave(example: audio streaming).
1041   * @retval HAL status
1042   */
1043 
1044 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive(I2S_HandleTypeDef *hi2s, const uint16_t *pTxData, uint16_t *pRxData,
1045                                             uint16_t Size, uint32_t Timeout)
1046 {
1047   uint32_t tmp_TxXferCount;
1048   uint32_t tmp_RxXferCount;
1049   uint32_t tickstart;
1050 
1051 #if defined (__GNUC__)
1052   __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->TXDR));
1053   __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->RXDR));
1054 #endif /* __GNUC__ */
1055 
1056   if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
1057   {
1058     return  HAL_ERROR;
1059   }
1060 
1061   if (hi2s->State != HAL_I2S_STATE_READY)
1062   {
1063     return HAL_BUSY;
1064   }
1065 
1066   /* Process Locked */
1067   __HAL_LOCK(hi2s);
1068 
1069   /* Init tickstart for timeout management*/
1070   tickstart = HAL_GetTick();
1071 
1072   hi2s->TxXferSize  = Size;
1073   hi2s->TxXferCount = Size;
1074   hi2s->pTxBuffPtr  = (const uint16_t *)pTxData;
1075   hi2s->RxXferSize  = Size;
1076   hi2s->RxXferCount = Size;
1077   hi2s->pRxBuffPtr  = pRxData;
1078 
1079   tmp_TxXferCount = hi2s->TxXferCount;
1080   tmp_RxXferCount = hi2s->RxXferCount;
1081 
1082   /* Set state and reset error code */
1083   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1084   hi2s->State = HAL_I2S_STATE_BUSY_TX_RX;
1085 
1086   /* Check if the I2S is already enabled */
1087   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
1088   {
1089     /* Enable I2S peripheral */
1090     __HAL_I2S_ENABLE(hi2s);
1091   }
1092 
1093   /* Start the transfer */
1094   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1095 
1096   while ((tmp_TxXferCount > 0UL) || (tmp_RxXferCount > 0UL))
1097   {
1098     if ((__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_TXP) == SET) && (tmp_TxXferCount != 0UL))
1099     {
1100       if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
1101       {
1102         /* Transmit data in 32 Bit mode */
1103         hi2s->Instance->TXDR = *((const uint32_t *)hi2s->pTxBuffPtr);
1104         hi2s->pTxBuffPtr += 2;
1105         tmp_TxXferCount--;
1106       }
1107       else
1108       {
1109         /* Transmit data in 16 Bit mode */
1110 #if defined (__GNUC__)
1111         *ptxdr_16bits = *((const uint16_t *)hi2s->pTxBuffPtr);
1112 #else
1113         *((__IO uint16_t *)&hi2s->Instance->TXDR) = *((const uint16_t *)hi2s->pTxBuffPtr);
1114 #endif /* __GNUC__ */
1115 
1116         hi2s->pTxBuffPtr++;
1117         tmp_TxXferCount--;
1118       }
1119 
1120       /* Check if an underrun occurs */
1121       if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET)
1122       {
1123         /* Clear underrun flag */
1124         __HAL_I2S_CLEAR_UDRFLAG(hi2s);
1125 
1126         /* Set the error code */
1127         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
1128       }
1129     }
1130 
1131     if ((__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_RXP) == SET) && (tmp_RxXferCount != 0UL))
1132     {
1133       if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
1134       {
1135         /* Receive data in 32 Bit mode */
1136         *((uint32_t *)hi2s->pRxBuffPtr) = hi2s->Instance->RXDR;
1137         hi2s->pRxBuffPtr += 2;
1138         tmp_RxXferCount--;
1139       }
1140       else
1141       {
1142         /* Receive data in 16 Bit mode */
1143 #if defined (__GNUC__)
1144         *((uint16_t *)hi2s->pRxBuffPtr) = *prxdr_16bits;
1145 #else
1146         *((uint16_t *)hi2s->pRxBuffPtr) = *((__IO uint16_t *)&hi2s->Instance->RXDR);
1147 #endif /* __GNUC__ */
1148         hi2s->pRxBuffPtr++;
1149         tmp_RxXferCount--;
1150       }
1151 
1152       /* Check if an overrun occurs */
1153       if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
1154       {
1155         /* Clear overrun flag */
1156         __HAL_I2S_CLEAR_OVRFLAG(hi2s);
1157 
1158         /* Set the error code */
1159         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
1160       }
1161     }
1162 
1163     /* Timeout management */
1164     if ((((HAL_GetTick() - tickstart) >=  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
1165     {
1166       /* Set the error code */
1167       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
1168       hi2s->State = HAL_I2S_STATE_READY;
1169       __HAL_UNLOCK(hi2s);
1170       return HAL_TIMEOUT;
1171     }
1172   }
1173 
1174   hi2s->State = HAL_I2S_STATE_READY;
1175   __HAL_UNLOCK(hi2s);
1176   return HAL_OK;
1177 }
1178 
1179 /**
1180   * @brief  Transmit an amount of data in non-blocking mode with Interrupt
1181   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1182   *         the configuration information for I2S module
1183   * @param  pData a 16-bit pointer to data buffer.
1184   * @param  Size number of data sample to be sent:
1185   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1186   *         configuration phase, the Size parameter means the number of 16-bit data length
1187   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1188   *         the Size parameter means the number of 16-bit data length.
1189   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1190   *         between Master and Slave(example: audio streaming).
1191   * @retval HAL status
1192   */
1193 HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, const uint16_t *pData, uint16_t Size)
1194 {
1195   if ((pData == NULL) || (Size == 0UL))
1196   {
1197     return  HAL_ERROR;
1198   }
1199 
1200   if (hi2s->State != HAL_I2S_STATE_READY)
1201   {
1202     return HAL_BUSY;
1203   }
1204 
1205   /* Process Locked */
1206   __HAL_LOCK(hi2s);
1207 
1208   /* Set state and reset error code */
1209   hi2s->State       = HAL_I2S_STATE_BUSY_TX;
1210   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
1211   hi2s->pTxBuffPtr  = (const uint16_t *)pData;
1212   hi2s->TxXferSize  = Size;
1213   hi2s->TxXferCount = Size;
1214 
1215   /* Initialize fields not used in handle to zero */
1216   hi2s->pRxBuffPtr  = NULL;
1217   hi2s->RxXferSize  = (uint16_t) 0UL;
1218   hi2s->RxXferCount = (uint16_t) 0UL;
1219 
1220   /* Set the function for IT treatment */
1221   if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
1222   {
1223     hi2s->TxISR = I2S_Transmit_32Bit_IT;
1224   }
1225   else
1226   {
1227     hi2s->TxISR = I2S_Transmit_16Bit_IT;
1228   }
1229 
1230   /* Check if the I2S is already enabled */
1231   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
1232   {
1233     /* Enable I2S peripheral */
1234     __HAL_I2S_ENABLE(hi2s);
1235   }
1236 
1237   /* Enable TXP and UDR interrupt */
1238   __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_UDR));
1239 
1240   /* Enable TIFRE interrupt if the mode is Slave  */
1241   if (hi2s->Init.Mode == I2S_MODE_SLAVE_TX)
1242   {
1243     __HAL_I2S_ENABLE_IT(hi2s, I2S_IT_FRE);
1244   }
1245 
1246   /* Start the transfer */
1247   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1248 
1249   __HAL_UNLOCK(hi2s);
1250   return HAL_OK;
1251 }
1252 
1253 /**
1254   * @brief  Receive an amount of data in non-blocking mode with Interrupt
1255   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1256   *         the configuration information for I2S module
1257   * @param  pData a 16-bit pointer to the Receive data buffer.
1258   * @param  Size number of data sample to be sent:
1259   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1260   *         configuration phase, the Size parameter means the number of 16-bit data length
1261   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1262   *         the Size parameter means the number of 16-bit data length.
1263   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1264   *         between Master and Slave(example: audio streaming).
1265   * @note   It is recommended to use DMA for the I2S receiver to avoid de-synchronization
1266   * between Master and Slave otherwise the I2S interrupt should be optimized.
1267   * @retval HAL status
1268   */
1269 HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
1270 {
1271   if ((pData == NULL) || (Size == 0UL))
1272   {
1273     return  HAL_ERROR;
1274   }
1275 
1276   if (hi2s->State != HAL_I2S_STATE_READY)
1277   {
1278     return HAL_BUSY;
1279   }
1280 
1281   /* Process Locked */
1282   __HAL_LOCK(hi2s);
1283 
1284   /* Set state and reset error code */
1285   hi2s->State       = HAL_I2S_STATE_BUSY_RX;
1286   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
1287   hi2s->pRxBuffPtr  = pData;
1288   hi2s->RxXferSize  = Size;
1289   hi2s->RxXferCount = Size;
1290 
1291   /* Initialize fields not used in handle to zero */
1292   hi2s->pTxBuffPtr  = NULL;
1293   hi2s->TxXferSize  = (uint16_t) 0UL;
1294   hi2s->TxXferCount = (uint16_t) 0UL;
1295 
1296   /* Set the function for IT treatment */
1297   if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
1298   {
1299     hi2s->RxISR = I2S_Receive_32Bit_IT;
1300   }
1301   else
1302   {
1303     hi2s->RxISR = I2S_Receive_16Bit_IT;
1304   }
1305 
1306   /* Check if the I2S is already enabled */
1307   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
1308   {
1309     /* Enable I2S peripheral */
1310     __HAL_I2S_ENABLE(hi2s);
1311   }
1312   /* Enable RXP and ERR interrupt */
1313   __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXP | I2S_IT_OVR));
1314 
1315   /* Enable TIFRE interrupt if the mode is Slave  */
1316   if (hi2s->Init.Mode == I2S_MODE_SLAVE_RX)
1317   {
1318     __HAL_I2S_ENABLE_IT(hi2s, I2S_IT_FRE);
1319   }
1320 
1321   /* Start the transfer */
1322   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1323 
1324   __HAL_UNLOCK(hi2s);
1325   return HAL_OK;
1326 }
1327 
1328 /**
1329   * @brief  Full-Duplex Transmit/Receive data in non-blocking mode using Interrupt
1330   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1331   *         the configuration information for I2S module
1332   * @param  pTxData a 16-bit pointer to the Transmit data buffer.
1333   * @param  pRxData a 16-bit pointer to the Receive data buffer.
1334   * @param  Size number of data sample to be sent:
1335   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1336   *         configuration phase, the Size parameter means the number of 16-bit data length
1337   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1338   *         the Size parameter means the number of 16-bit data length.
1339   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1340   *         between Master and Slave(example: audio streaming).
1341   * @retval HAL status
1342   */
1343 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s, const uint16_t *pTxData, uint16_t *pRxData,
1344                                                uint16_t Size)
1345 {
1346   if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
1347   {
1348     return  HAL_ERROR;
1349   }
1350 
1351   if (hi2s->State != HAL_I2S_STATE_READY)
1352   {
1353     return HAL_BUSY;
1354   }
1355 
1356   /* Process Locked */
1357   __HAL_LOCK(hi2s);
1358 
1359   hi2s->pTxBuffPtr  = (const uint16_t *)pTxData;
1360   hi2s->pRxBuffPtr  = pRxData;
1361 
1362   hi2s->TxXferSize  = Size;
1363   hi2s->TxXferCount = Size;
1364   hi2s->RxXferSize  = Size;
1365   hi2s->RxXferCount = Size;
1366 
1367   hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
1368   hi2s->State     = HAL_I2S_STATE_BUSY_TX_RX;
1369 
1370 
1371   /* Set the function for IT treatment */
1372   if ((hi2s->Init.DataFormat == I2S_DATAFORMAT_24B) || (hi2s->Init.DataFormat == I2S_DATAFORMAT_32B))
1373   {
1374     hi2s->TxISR = I2S_Transmit_32Bit_IT;
1375     hi2s->RxISR = I2S_Receive_32Bit_IT;
1376   }
1377   else
1378   {
1379     hi2s->TxISR = I2S_Transmit_16Bit_IT;
1380     hi2s->RxISR = I2S_Receive_16Bit_IT;
1381   }
1382 
1383   /* Check if the I2S is already enabled */
1384   if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
1385   {
1386     /* Enable I2S peripheral */
1387     __HAL_I2S_ENABLE(hi2s);
1388   }
1389 
1390   /* Enable TXP, RXP, DXP, UDR, OVR interrupts */
1391   __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_RXP | I2S_IT_DXP | I2S_IT_UDR | I2S_IT_OVR));
1392 
1393   /* Enable TIFRE interrupt if the mode is Slave  */
1394   if (hi2s->Init.Mode == I2S_MODE_SLAVE_FULLDUPLEX)
1395   {
1396     __HAL_I2S_ENABLE_IT(hi2s, I2S_IT_FRE);
1397   }
1398 
1399   /* Start the transfer */
1400   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1401 
1402   __HAL_UNLOCK(hi2s);
1403   return HAL_OK;
1404 
1405 }
1406 
1407 /**
1408   * @brief  Transmit an amount of data in non-blocking mode with DMA
1409   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1410   *         the configuration information for I2S module
1411   * @param  pData a 16-bit pointer to the Transmit data buffer.
1412   * @param  Size number of data sample to be sent:
1413   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1414   *         configuration phase, the Size parameter means the number of 16-bit data length
1415   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1416   *         the Size parameter means the number of 16-bit data length.
1417   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1418   *         between Master and Slave(example: audio streaming).
1419   * @retval HAL status
1420   */
1421 HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, const uint16_t *pData, uint16_t Size)
1422 {
1423   HAL_StatusTypeDef errorcode = HAL_OK;
1424 
1425   if ((pData == NULL) || (Size == 0UL))
1426   {
1427     return  HAL_ERROR;
1428   }
1429 
1430   if (hi2s->State != HAL_I2S_STATE_READY)
1431   {
1432     return HAL_BUSY;
1433   }
1434 
1435   /* Process Locked */
1436   __HAL_LOCK(hi2s);
1437 
1438   /* Set state and reset error code */
1439   hi2s->State       = HAL_I2S_STATE_BUSY_TX;
1440   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
1441   hi2s->pTxBuffPtr  = (const uint16_t *)pData;
1442   hi2s->TxXferSize  = Size;
1443   hi2s->TxXferCount = Size;
1444 
1445   /* Init field not used in handle to zero */
1446   hi2s->pRxBuffPtr  = NULL;
1447   hi2s->RxXferSize  = (uint16_t)0UL;
1448   hi2s->RxXferCount = (uint16_t)0UL;
1449 
1450   /* Set the I2S Tx DMA Half transfer complete callback */
1451   hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt;
1452 
1453   /* Set the I2S Tx DMA transfer complete callback */
1454   hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt;
1455 
1456   /* Set the DMA error callback */
1457   hi2s->hdmatx->XferErrorCallback = I2S_DMAError;
1458 
1459   /* Enable the Tx DMA Stream/Channel */
1460   if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmatx, (uint32_t)hi2s->pTxBuffPtr, (uint32_t)&hi2s->Instance->TXDR,
1461                                  hi2s->TxXferCount))
1462   {
1463     /* Update I2S error code */
1464     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1465     hi2s->State = HAL_I2S_STATE_READY;
1466 
1467     __HAL_UNLOCK(hi2s);
1468     errorcode = HAL_ERROR;
1469     return errorcode;
1470   }
1471 
1472   /* Check if the I2S Tx request is already enabled */
1473   if (HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN))
1474   {
1475     /* Enable Tx DMA Request */
1476     SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
1477   }
1478 
1479   /* Check if the I2S is already enabled */
1480   if (HAL_IS_BIT_CLR(hi2s->Instance->CR1, SPI_CR1_SPE))
1481   {
1482     /* Enable I2S peripheral */
1483     __HAL_I2S_ENABLE(hi2s);
1484   }
1485 
1486   /* Start the transfer */
1487   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1488 
1489   __HAL_UNLOCK(hi2s);
1490   return errorcode;
1491 }
1492 
1493 /**
1494   * @brief  Receive an amount of data in non-blocking mode with DMA
1495   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1496   *         the configuration information for I2S module
1497   * @param  pData a 16-bit pointer to the Receive data buffer.
1498   * @param  Size number of data sample to be sent:
1499   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1500   *         configuration phase, the Size parameter means the number of 16-bit data length
1501   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1502   *         the Size parameter means the number of 16-bit data length.
1503   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1504   *         between Master and Slave(example: audio streaming).
1505   * @retval HAL status
1506   */
1507 HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
1508 {
1509   HAL_StatusTypeDef errorcode = HAL_OK;
1510 
1511   if ((pData == NULL) || (Size == 0UL))
1512   {
1513     return HAL_ERROR;
1514   }
1515 
1516   if (hi2s->State != HAL_I2S_STATE_READY)
1517   {
1518     return HAL_BUSY;
1519   }
1520 
1521   /* Process Locked */
1522   __HAL_LOCK(hi2s);
1523 
1524   /* Set state and reset error code */
1525   hi2s->State       = HAL_I2S_STATE_BUSY_RX;
1526   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
1527   hi2s->pRxBuffPtr  = pData;
1528   hi2s->RxXferSize  = Size;
1529   hi2s->RxXferCount = Size;
1530 
1531   /* Init field not used in handle to zero */
1532   hi2s->pTxBuffPtr  = NULL;
1533   hi2s->TxXferSize  = (uint16_t)0UL;
1534   hi2s->TxXferCount = (uint16_t)0UL;
1535 
1536 
1537   /* Set the I2S Rx DMA Half transfer complete callback */
1538   hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt;
1539 
1540   /* Set the I2S Rx DMA transfer complete callback */
1541   hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt;
1542 
1543   /* Set the DMA error callback */
1544   hi2s->hdmarx->XferErrorCallback = I2S_DMAError;
1545 
1546   /* Enable the Rx DMA Stream/Channel */
1547   if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->RXDR, (uint32_t)hi2s->pRxBuffPtr,
1548                                  hi2s->RxXferCount))
1549   {
1550     /* Update I2S error code */
1551     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1552     hi2s->State = HAL_I2S_STATE_READY;
1553     errorcode = HAL_ERROR;
1554     __HAL_UNLOCK(hi2s);
1555     return errorcode;
1556   }
1557 
1558   /* Check if the I2S Rx request is already enabled */
1559   if (HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN))
1560   {
1561     /* Enable Rx DMA Request */
1562     SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
1563   }
1564 
1565   /* Check if the I2S is already enabled */
1566   if (HAL_IS_BIT_CLR(hi2s->Instance->CR1, SPI_CR1_SPE))
1567   {
1568     /* Enable I2S peripheral */
1569     __HAL_I2S_ENABLE(hi2s);
1570   }
1571 
1572   /* Start the transfer */
1573   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1574 
1575   __HAL_UNLOCK(hi2s);
1576   return errorcode;
1577 }
1578 
1579 /**
1580   * @brief  Full-Duplex Transmit/Receive data in non-blocking mode using DMA
1581   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1582   *         the configuration information for I2S module
1583   * @param  pTxData a 16-bit pointer to the Transmit data buffer.
1584   * @param  pRxData a 16-bit pointer to the Receive data buffer.
1585   * @param  Size number of data sample to be sent:
1586   * @note   When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
1587   *         configuration phase, the Size parameter means the number of 16-bit data length
1588   *         in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
1589   *         the Size parameter means the number of 16-bit data length.
1590   * @note   The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
1591   *         between Master and Slave(example: audio streaming).
1592   * @retval HAL status
1593   */
1594 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_DMA(I2S_HandleTypeDef *hi2s, const uint16_t *pTxData, uint16_t *pRxData,
1595                                                 uint16_t Size)
1596 {
1597   HAL_StatusTypeDef errorcode = HAL_OK;
1598 
1599 
1600   if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
1601   {
1602     return  HAL_ERROR;
1603   }
1604 
1605   if (hi2s->State != HAL_I2S_STATE_READY)
1606   {
1607     return HAL_BUSY;
1608   }
1609 
1610   /* Process Locked */
1611   __HAL_LOCK(hi2s);
1612 
1613   hi2s->pTxBuffPtr = (const uint16_t *)pTxData;
1614   hi2s->pRxBuffPtr = pRxData;
1615 
1616   hi2s->TxXferSize  = Size;
1617   hi2s->TxXferCount = Size;
1618   hi2s->RxXferSize  = Size;
1619   hi2s->RxXferCount = Size;
1620 
1621   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
1622   hi2s->State       = HAL_I2S_STATE_BUSY_TX_RX;
1623 
1624   /* Reset the Tx/Rx DMA bits */
1625   CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN);
1626 
1627   /* Set the I2S Rx DMA Half transfer complete callback */
1628   hi2s->hdmarx->XferHalfCpltCallback = I2SEx_DMATxRxHalfCplt;
1629 
1630   /* Set the I2S Rx DMA transfer complete callback */
1631   hi2s->hdmarx->XferCpltCallback  = I2SEx_DMATxRxCplt;
1632 
1633   /* Set the I2S Rx DMA error callback */
1634   hi2s->hdmarx->XferErrorCallback = I2S_DMAError;
1635   /* Enable the Tx DMA Stream/Channel */
1636   if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmatx, (uint32_t)hi2s->pTxBuffPtr, (uint32_t)&hi2s->Instance->TXDR,
1637                                  hi2s->TxXferCount))
1638   {
1639     /* Update I2S error code */
1640     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1641     hi2s->State = HAL_I2S_STATE_READY;
1642 
1643     __HAL_UNLOCK(hi2s);
1644     errorcode = HAL_ERROR;
1645     return errorcode;
1646   }
1647 
1648   /* Check if the I2S Tx request is already enabled */
1649   if (HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN))
1650   {
1651     /* Enable Tx DMA Request */
1652     SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
1653   }
1654 
1655   /* Enable the Rx DMA Stream/Channel */
1656   if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->RXDR, (uint32_t)hi2s->pRxBuffPtr,
1657                                  hi2s->RxXferCount))
1658   {
1659     /* Update I2S error code */
1660     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1661     hi2s->State = HAL_I2S_STATE_READY;
1662     errorcode = HAL_ERROR;
1663     __HAL_UNLOCK(hi2s);
1664     return errorcode;
1665   }
1666 
1667   /* Check if the I2S Rx request is already enabled */
1668   if (HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN))
1669   {
1670     /* Enable Rx DMA Request */
1671     SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
1672   }
1673 
1674   /* Check if the I2S is already enabled */
1675   if (HAL_IS_BIT_CLR(hi2s->Instance->CR1, SPI_CR1_SPE))
1676   {
1677     /* Enable I2S peripheral */
1678     __HAL_I2S_ENABLE(hi2s);
1679   }
1680 
1681   /* Start the transfer */
1682   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1683 
1684   __HAL_UNLOCK(hi2s);
1685   return errorcode;
1686 }
1687 
1688 /**
1689   * @brief  Pauses the audio DMA Stream/Channel playing from the Media.
1690   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1691   *         the configuration information for I2S module
1692   * @retval HAL status
1693   */
1694 HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s)
1695 {
1696   /* Process Locked */
1697   __HAL_LOCK(hi2s);
1698 
1699   uint32_t tickstart;
1700 
1701   /* Get tick */
1702   tickstart = HAL_GetTick();
1703 
1704 
1705   /* Check if the I2S peripheral is in master mode */
1706   if (IS_I2S_MASTER(hi2s->Init.Mode))
1707   {
1708     /* Check if there is a transfer on-going */
1709     if (HAL_IS_BIT_SET(hi2s->Instance->CR1, SPI_CR1_CSTART) == 0UL)
1710     {
1711       /* Set error code to no on going transfer */
1712       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_NO_OGT);
1713       hi2s->State = HAL_I2S_STATE_READY;
1714 
1715       __HAL_UNLOCK(hi2s);
1716       return HAL_ERROR;
1717     }
1718 
1719     SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSUSP);
1720 
1721     while (HAL_IS_BIT_SET(hi2s->Instance->CR1, SPI_CR1_CSTART) != 0UL)
1722     {
1723       if ((((HAL_GetTick() - tickstart) >=  I2S_TIMEOUT) && (I2S_TIMEOUT != HAL_MAX_DELAY)) || (I2S_TIMEOUT == 0U))
1724       {
1725         /* Set the I2S State ready */
1726         hi2s->State = HAL_I2S_STATE_READY;
1727 
1728         /* Process Unlocked */
1729         __HAL_UNLOCK(hi2s);
1730 
1731         SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
1732         hi2s->State = HAL_I2S_STATE_READY;
1733         return HAL_TIMEOUT;
1734       }
1735     }
1736 
1737     /* Disable I2S peripheral */
1738     __HAL_I2S_DISABLE(hi2s);
1739 
1740     hi2s->State = HAL_I2S_STATE_READY;
1741 
1742     /* Process Unlocked */
1743     __HAL_UNLOCK(hi2s);
1744 
1745     return HAL_OK;
1746   }
1747   else
1748   {
1749     /* Set error code to not supported */
1750     SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_NOT_SUPPORTED);
1751     hi2s->State = HAL_I2S_STATE_READY;
1752 
1753     /* Process Unlocked */
1754     __HAL_UNLOCK(hi2s);
1755 
1756     return HAL_ERROR;
1757   }
1758 }
1759 
1760 /**
1761   * @brief  Resumes the audio DMA Stream/Channel playing from the Media.
1762   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1763   *         the configuration information for I2S module
1764   * @retval HAL status
1765   */
1766 HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s)
1767 {
1768   /* Process Locked */
1769   __HAL_LOCK(hi2s);
1770 
1771   if (hi2s->State != HAL_I2S_STATE_READY)
1772   {
1773     hi2s->State = HAL_I2S_STATE_READY;
1774 
1775     __HAL_UNLOCK(hi2s);
1776     return HAL_ERROR;
1777   }
1778 
1779   /* Set state and reset error code */
1780   hi2s->State       = HAL_I2S_STATE_BUSY;
1781   hi2s->ErrorCode   = HAL_I2S_ERROR_NONE;
1782 
1783   /* Enable I2S peripheral */
1784   __HAL_I2S_ENABLE(hi2s);
1785 
1786   /* Start the transfer */
1787   SET_BIT(hi2s->Instance->CR1, SPI_CR1_CSTART);
1788 
1789   /* Process Unlocked */
1790   __HAL_UNLOCK(hi2s);
1791 
1792   return HAL_OK;
1793 }
1794 
1795 /**
1796   * @brief  Stops the audio DMA Stream/Channel playing from the Media.
1797   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1798   *         the configuration information for I2S module
1799   * @retval HAL status
1800   */
1801 HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s)
1802 {
1803   HAL_StatusTypeDef errorcode = HAL_OK;
1804   /* The Lock is not implemented on this API to allow the user application
1805      to call the HAL I2S API under callbacks HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback()
1806      when calling HAL_DMA_Abort() API the DMA TX or RX Transfer complete interrupt is generated
1807      and the correspond call back is executed HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback()
1808      */
1809 
1810   /* Disable the I2S Tx/Rx DMA requests */
1811   CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
1812   CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
1813 
1814   /* Abort the I2S DMA tx Stream/Channel */
1815   if (hi2s->hdmatx != NULL)
1816   {
1817     /* Disable the I2S DMA tx Stream/Channel */
1818     if (HAL_OK != HAL_DMA_Abort(hi2s->hdmatx))
1819     {
1820       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1821       errorcode = HAL_ERROR;
1822     }
1823   }
1824 
1825   /* Abort the I2S DMA rx Stream/Channel */
1826   if (hi2s->hdmarx != NULL)
1827   {
1828     /* Disable the I2S DMA rx Stream/Channel */
1829     if (HAL_OK != HAL_DMA_Abort(hi2s->hdmarx))
1830     {
1831       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
1832       errorcode = HAL_ERROR;
1833     }
1834   }
1835 
1836   /* Disable I2S peripheral */
1837   __HAL_I2S_DISABLE(hi2s);
1838 
1839   hi2s->State = HAL_I2S_STATE_READY;
1840 
1841   return errorcode;
1842 }
1843 
1844 /**
1845   * @brief  This function handles I2S interrupt request.
1846   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1847   *         the configuration information for I2S module
1848   * @retval None
1849   */
1850 void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s)
1851 {
1852   uint32_t i2sier   = hi2s->Instance->IER;
1853   uint32_t i2ssr    = hi2s->Instance->SR;
1854   uint32_t trigger  = i2sier & i2ssr;
1855 
1856   if (hi2s->State == HAL_I2S_STATE_BUSY_RX)
1857   {
1858     /* I2S in mode Receiver ------------------------------------------------*/
1859     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_RXP) && HAL_IS_BIT_CLR(trigger, I2S_FLAG_OVR))
1860     {
1861       hi2s->RxISR(hi2s);
1862     }
1863 
1864     /* I2S Overrun error interrupt occurred -------------------------------------*/
1865     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_OVR))
1866     {
1867       /* Disable RXP and ERR interrupt */
1868       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXP | I2S_IT_ERR));
1869 
1870       /* Clear Overrun flag */
1871       __HAL_I2S_CLEAR_OVRFLAG(hi2s);
1872 
1873       /* Set the I2S State ready */
1874       hi2s->State = HAL_I2S_STATE_READY;
1875 
1876 
1877       /* Set the error code and execute error callback*/
1878       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
1879       /* Call user error callback */
1880 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
1881       hi2s->ErrorCallback(hi2s);
1882 #else
1883       HAL_I2S_ErrorCallback(hi2s);
1884 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1885     }
1886   }
1887 
1888   if (hi2s->State == HAL_I2S_STATE_BUSY_TX)
1889   {
1890     /* I2S in mode Transmitter -----------------------------------------------*/
1891     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_TXP) && HAL_IS_BIT_CLR(trigger, I2S_FLAG_UDR))
1892     {
1893       hi2s->TxISR(hi2s);
1894     }
1895 
1896     /* I2S Underrun error interrupt occurred --------------------------------*/
1897     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_UDR))
1898     {
1899       /* Disable TXP and ERR interrupt */
1900       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_ERR));
1901 
1902       /* Clear Underrun flag */
1903       __HAL_I2S_CLEAR_UDRFLAG(hi2s);
1904 
1905       /* Set the I2S State ready */
1906       hi2s->State = HAL_I2S_STATE_READY;
1907 
1908       /* Set the error code and execute error callback*/
1909       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
1910       /* Call user error callback */
1911 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
1912       hi2s->ErrorCallback(hi2s);
1913 #else
1914       HAL_I2S_ErrorCallback(hi2s);
1915 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1916     }
1917   }
1918   if (hi2s->State == HAL_I2S_STATE_BUSY_TX_RX)
1919   {
1920     /* I2S in mode Transmitter -----------------------------------------------*/
1921     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_DXP))
1922     {
1923       hi2s->TxISR(hi2s);
1924       hi2s->RxISR(hi2s);
1925     }
1926     /* I2S in mode Receiver ------------------------------------------------*/
1927     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_RXP) && HAL_IS_BIT_CLR(trigger, I2S_FLAG_DXP))
1928     {
1929       hi2s->RxISR(hi2s);
1930     }
1931     /* I2S in mode Transmitter -----------------------------------------------*/
1932     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_TXP) && HAL_IS_BIT_CLR(trigger, I2S_FLAG_DXP))
1933     {
1934       hi2s->TxISR(hi2s);
1935     }
1936 
1937     /* I2S Underrun error interrupt occurred --------------------------------*/
1938     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_UDR))
1939     {
1940       /* Disable TXP, RXP and ERR interrupt */
1941       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_RXP | I2S_IT_ERR));
1942 
1943       /* Clear Underrun flag */
1944       __HAL_I2S_CLEAR_UDRFLAG(hi2s);
1945 
1946       /* Set the I2S State ready */
1947       hi2s->State = HAL_I2S_STATE_READY;
1948 
1949       /* Set the error code and execute error callback*/
1950       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
1951       /* Call user error callback */
1952 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
1953       hi2s->ErrorCallback(hi2s);
1954 #else
1955       HAL_I2S_ErrorCallback(hi2s);
1956 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1957     }
1958 
1959     /* I2S Overrun error interrupt occurred -------------------------------------*/
1960     if (HAL_IS_BIT_SET(trigger, I2S_FLAG_OVR))
1961     {
1962       /* Disable TXP, RXP and ERR interrupt */
1963       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_RXP | I2S_IT_ERR));
1964 
1965       /* Clear Overrun flag */
1966       __HAL_I2S_CLEAR_OVRFLAG(hi2s);
1967 
1968       /* Set the I2S State ready */
1969       hi2s->State = HAL_I2S_STATE_READY;
1970 
1971 
1972       /* Set the error code and execute error callback*/
1973       SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
1974 
1975       /* Call user error callback */
1976 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
1977       hi2s->ErrorCallback(hi2s);
1978 #else
1979       HAL_I2S_ErrorCallback(hi2s);
1980 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
1981     }
1982   }
1983 }
1984 
1985 /**
1986   * @brief  Tx Transfer Half completed callbacks
1987   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
1988   *         the configuration information for I2S module
1989   * @retval None
1990   */
1991 __weak void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
1992 {
1993   /* Prevent unused argument(s) compilation warning */
1994   UNUSED(hi2s);
1995 
1996   /* NOTE : This function Should not be modified, when the callback is needed,
1997             the HAL_I2S_TxHalfCpltCallback could be implemented in the user file
1998    */
1999 }
2000 
2001 /**
2002   * @brief  Tx Transfer completed callbacks
2003   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2004   *         the configuration information for I2S module
2005   * @retval None
2006   */
2007 __weak void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
2008 {
2009   /* Prevent unused argument(s) compilation warning */
2010   UNUSED(hi2s);
2011 
2012   /* NOTE : This function Should not be modified, when the callback is needed,
2013             the HAL_I2S_TxCpltCallback could be implemented in the user file
2014    */
2015 }
2016 
2017 /**
2018   * @brief  Rx Transfer half completed callbacks
2019   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2020   *         the configuration information for I2S module
2021   * @retval None
2022   */
2023 __weak void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
2024 {
2025   /* Prevent unused argument(s) compilation warning */
2026   UNUSED(hi2s);
2027 
2028   /* NOTE : This function Should not be modified, when the callback is needed,
2029             the HAL_I2S_RxHalfCpltCallback could be implemented in the user file
2030    */
2031 }
2032 
2033 /**
2034   * @brief  Rx Transfer completed callbacks
2035   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2036   *         the configuration information for I2S module
2037   * @retval None
2038   */
2039 __weak void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
2040 {
2041   /* Prevent unused argument(s) compilation warning */
2042   UNUSED(hi2s);
2043 
2044   /* NOTE : This function Should not be modified, when the callback is needed,
2045             the HAL_I2S_RxCpltCallback could be implemented in the user file
2046    */
2047 }
2048 
2049 /**
2050   * @brief  Rx Transfer half completed callbacks
2051   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2052   *         the configuration information for I2S module
2053   * @retval None
2054   */
2055 __weak void HAL_I2SEx_TxRxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
2056 {
2057   /* Prevent unused argument(s) compilation warning */
2058   UNUSED(hi2s);
2059 
2060   /* NOTE : This function Should not be modified, when the callback is needed,
2061             the HAL_I2S_RxHalfCpltCallback could be implemented in the user file
2062    */
2063 }
2064 
2065 /**
2066   * @brief  Rx Transfer completed callbacks
2067   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2068   *         the configuration information for I2S module
2069   * @retval None
2070   */
2071 __weak void HAL_I2SEx_TxRxCpltCallback(I2S_HandleTypeDef *hi2s)
2072 {
2073   /* Prevent unused argument(s) compilation warning */
2074   UNUSED(hi2s);
2075 
2076   /* NOTE : This function Should not be modified, when the callback is needed,
2077             the HAL_I2S_RxCpltCallback could be implemented in the user file
2078    */
2079 }
2080 
2081 /**
2082   * @brief  I2S error callbacks
2083   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2084   *         the configuration information for I2S module
2085   * @retval None
2086   */
2087 __weak void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s)
2088 {
2089   /* Prevent unused argument(s) compilation warning */
2090   UNUSED(hi2s);
2091 
2092   /* NOTE : This function Should not be modified, when the callback is needed,
2093             the HAL_I2S_ErrorCallback could be implemented in the user file
2094    */
2095 }
2096 
2097 /**
2098   * @}
2099   */
2100 
2101 /** @defgroup I2S_Exported_Functions_Group3 Peripheral State and Errors functions
2102   * @ingroup RTEMSBSPsARMSTM32H7
2103   *  @brief   Peripheral State functions
2104   *
2105 @verbatim
2106  ===============================================================================
2107                       ##### Peripheral State and Errors functions #####
2108  ===============================================================================
2109     [..]
2110     This subsection permits to get in run-time the status of the peripheral
2111     and the data flow.
2112 
2113 @endverbatim
2114   * @{
2115   */
2116 
2117 /**
2118   * @brief  Return the I2S state
2119   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2120   *         the configuration information for I2S module
2121   * @retval HAL state
2122   */
2123 HAL_I2S_StateTypeDef HAL_I2S_GetState(const I2S_HandleTypeDef *hi2s)
2124 {
2125   return hi2s->State;
2126 }
2127 
2128 /**
2129   * @brief  Return the I2S error code
2130   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2131   *         the configuration information for I2S module
2132   * @retval I2S Error Code
2133   */
2134 uint32_t HAL_I2S_GetError(const I2S_HandleTypeDef *hi2s)
2135 {
2136   return hi2s->ErrorCode;
2137 }
2138 /**
2139   * @}
2140   */
2141 
2142 /**
2143   * @}
2144   */
2145 
2146 /** @addtogroup I2S_Private_Functions
2147   * @{
2148   */
2149 /**
2150   * @brief  DMA I2S transmit process complete callback
2151   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2152   *                the configuration information for the specified DMA module.
2153   * @retval None
2154   */
2155 static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma)
2156 {
2157   /* Derogation MISRAC2012-Rule-11.5 */
2158   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2159 
2160   /* if DMA is configured in DMA_NORMAL Mode */
2161   if (hdma->Init.Mode == DMA_NORMAL)
2162   {
2163     /* Disable Tx DMA Request */
2164     CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
2165 
2166     hi2s->TxXferCount = (uint16_t) 0UL;
2167     hi2s->State = HAL_I2S_STATE_READY;
2168   }
2169   /* Call user Tx complete callback */
2170 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2171   hi2s->TxCpltCallback(hi2s);
2172 #else
2173   HAL_I2S_TxCpltCallback(hi2s);
2174 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2175 }
2176 
2177 /**
2178   * @brief  DMA I2S transmit process half complete callback
2179   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2180   *         the configuration information for the specified DMA module.
2181   * @retval None
2182   */
2183 static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
2184 {
2185   /* Derogation MISRAC2012-Rule-11.5 */
2186   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2187 
2188   /* Call user Tx half complete callback */
2189 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2190   hi2s->TxHalfCpltCallback(hi2s);
2191 #else
2192   HAL_I2S_TxHalfCpltCallback(hi2s);
2193 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2194 }
2195 
2196 /**
2197   * @brief  DMA I2S receive process complete callback
2198   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2199   *         the configuration information for the specified DMA module.
2200   * @retval None
2201   */
2202 static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma)
2203 {
2204   /* Derogation MISRAC2012-Rule-11.5 */
2205   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2206 
2207   /* if DMA is configured in DMA_NORMAL Mode */
2208   if (hdma->Init.Mode == DMA_NORMAL)
2209   {
2210     /* Disable Rx DMA Request */
2211     CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
2212     hi2s->RxXferCount = (uint16_t)0UL;
2213     hi2s->State = HAL_I2S_STATE_READY;
2214   }
2215   /* Call user Rx complete callback */
2216 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2217   hi2s->RxCpltCallback(hi2s);
2218 #else
2219   HAL_I2S_RxCpltCallback(hi2s);
2220 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2221 }
2222 
2223 /**
2224   * @brief  DMA I2S receive process half complete callback
2225   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2226   *         the configuration information for the specified DMA module.
2227   * @retval None
2228   */
2229 static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
2230 {
2231   /* Derogation MISRAC2012-Rule-11.5 */
2232   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2233 
2234   /* Call user Rx half complete callback */
2235 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2236   hi2s->RxHalfCpltCallback(hi2s);
2237 #else
2238   HAL_I2S_RxHalfCpltCallback(hi2s);
2239 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2240 }
2241 
2242 /**
2243   * @brief  DMA I2S transmit receive process complete callback
2244   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2245   *               the configuration information for the specified DMA module.
2246   * @retval None
2247   */
2248 static void I2SEx_DMATxRxCplt(DMA_HandleTypeDef *hdma)
2249 {
2250   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2251 
2252   /* if DMA is configured in DMA_NORMAL Mode */
2253   if (hdma->Init.Mode == DMA_NORMAL)
2254   {
2255     /* Disable Tx DMA Request */
2256     CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
2257     hi2s->TxXferCount = (uint16_t) 0UL;
2258 
2259     /* Disable Rx DMA Request */
2260     CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
2261     hi2s->RxXferCount = (uint16_t)0UL;
2262 
2263     /* Updated HAL State */
2264     hi2s->State = HAL_I2S_STATE_READY;
2265   }
2266 
2267   /* Call user TxRx complete callback */
2268 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
2269   hi2s->TxRxCpltCallback(hi2s);
2270 #else
2271   HAL_I2SEx_TxRxCpltCallback(hi2s);
2272 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2273 }
2274 
2275 /**
2276   * @brief  DMA I2S transmit receive process half complete callback
2277   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2278   *               the configuration information for the specified DMA module.
2279   * @retval None
2280   */
2281 static void I2SEx_DMATxRxHalfCplt(DMA_HandleTypeDef *hdma)
2282 {
2283   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2284 
2285   /* Call user TxRx Half complete callback */
2286 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
2287   hi2s->TxRxHalfCpltCallback(hi2s);
2288 #else
2289   HAL_I2SEx_TxRxHalfCpltCallback(hi2s);
2290 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2291 }
2292 
2293 /**
2294   * @brief  DMA I2S communication error callback
2295   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
2296   *         the configuration information for the specified DMA module.
2297   * @retval None
2298   */
2299 static void I2S_DMAError(DMA_HandleTypeDef *hdma)
2300 {
2301   /* Derogation MISRAC2012-Rule-11.5 */
2302   I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2303 
2304   /* Disable Rx and Tx DMA Request */
2305   CLEAR_BIT(hi2s->Instance->CFG1, (SPI_CFG1_RXDMAEN | SPI_CFG1_TXDMAEN));
2306   hi2s->TxXferCount = (uint16_t) 0UL;
2307   hi2s->RxXferCount = (uint16_t) 0UL;
2308 
2309   hi2s->State = HAL_I2S_STATE_READY;
2310 
2311   /* Set the error code and execute error callback*/
2312   SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
2313   /* Call user error callback */
2314 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2315   hi2s->ErrorCallback(hi2s);
2316 #else
2317   HAL_I2S_ErrorCallback(hi2s);
2318 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2319 }
2320 
2321 /**
2322   * @brief  Manage the transmission 16-bit in Interrupt context
2323   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2324   *         the configuration information for I2S module
2325   * @retval None
2326   */
2327 static void I2S_Transmit_16Bit_IT(I2S_HandleTypeDef *hi2s)
2328 {
2329   /* Transmit data */
2330 #if defined (__GNUC__)
2331   __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->TXDR));
2332 
2333   *ptxdr_16bits = *((const uint16_t *)hi2s->pTxBuffPtr);
2334 #else
2335   *((__IO uint16_t *)&hi2s->Instance->TXDR) = *((const uint16_t *)hi2s->pTxBuffPtr);
2336 #endif /* __GNUC__ */
2337   hi2s->pTxBuffPtr++;
2338   hi2s->TxXferCount--;
2339 
2340   if (hi2s->TxXferCount == 0UL)
2341   {
2342     /* Disable TXP and ERR interrupt */
2343     __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_ERR));
2344 
2345     if ((hi2s->Init.Mode == I2S_MODE_SLAVE_TX) || (hi2s->Init.Mode == I2S_MODE_MASTER_TX))
2346     {
2347       hi2s->State = HAL_I2S_STATE_READY;
2348 
2349       /* Call user Tx complete callback */
2350 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2351       hi2s->TxCpltCallback(hi2s);
2352 #else
2353       HAL_I2S_TxCpltCallback(hi2s);
2354 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2355     }
2356   }
2357 }
2358 
2359 /**
2360   * @brief  Manage the transmission 32-bit in Interrupt context
2361   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2362   *         the configuration information for I2S module
2363   * @retval None
2364   */
2365 static void I2S_Transmit_32Bit_IT(I2S_HandleTypeDef *hi2s)
2366 {
2367   /* Transmit data */
2368   hi2s->Instance->TXDR = *((const uint32_t *)hi2s->pTxBuffPtr);
2369   hi2s->pTxBuffPtr += 2;
2370   hi2s->TxXferCount--;
2371 
2372   if (hi2s->TxXferCount == 0UL)
2373   {
2374     /* Disable TXP and ERR interrupt */
2375     __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_ERR));
2376 
2377     if ((hi2s->Init.Mode == I2S_MODE_SLAVE_TX) || (hi2s->Init.Mode == I2S_MODE_MASTER_TX))
2378     {
2379       hi2s->State = HAL_I2S_STATE_READY;
2380 
2381       /* Call user Tx complete callback */
2382 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2383       hi2s->TxCpltCallback(hi2s);
2384 #else
2385       HAL_I2S_TxCpltCallback(hi2s);
2386 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2387     }
2388   }
2389 }
2390 
2391 /**
2392   * @brief  Manage the reception 16-bit in Interrupt context
2393   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2394   *         the configuration information for I2S module
2395   * @retval None
2396   */
2397 static void I2S_Receive_16Bit_IT(I2S_HandleTypeDef *hi2s)
2398 {
2399   /* Receive data */
2400 #if defined (__GNUC__)
2401   __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hi2s->Instance->RXDR));
2402 
2403   *((uint16_t *)hi2s->pRxBuffPtr) = *prxdr_16bits;
2404 #else
2405   *((uint16_t *)hi2s->pRxBuffPtr) = *((__IO uint16_t *)&hi2s->Instance->RXDR);
2406 #endif /* __GNUC__ */
2407   hi2s->pRxBuffPtr++;
2408   hi2s->RxXferCount--;
2409 
2410   if (hi2s->RxXferCount == 0UL)
2411   {
2412     if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode))
2413     {
2414       /* Disable TXP, RXP, DXP, ERR interrupts */
2415       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_RXP | I2S_IT_DXP | I2S_IT_ERR));
2416     }
2417     else
2418     {
2419       /* Disable RXP and ERR interrupt */
2420       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXP | I2S_IT_ERR));
2421     }
2422 
2423     hi2s->State = HAL_I2S_STATE_READY;
2424     /* Call user Rx complete callback */
2425 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2426     if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode))
2427     {
2428       hi2s->TxRxCpltCallback(hi2s);
2429     }
2430     else
2431     {
2432       hi2s->RxCpltCallback(hi2s);
2433     }
2434 #else
2435     if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode))
2436     {
2437       HAL_I2SEx_TxRxCpltCallback(hi2s);
2438     }
2439     else
2440     {
2441       HAL_I2S_RxCpltCallback(hi2s);
2442     }
2443 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2444   }
2445 }
2446 
2447 /**
2448   * @brief  Manage the reception 32-bit in Interrupt context
2449   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2450   *         the configuration information for I2S module
2451   * @retval None
2452   */
2453 static void I2S_Receive_32Bit_IT(I2S_HandleTypeDef *hi2s)
2454 {
2455   /* Receive data */
2456   *((uint32_t *)hi2s->pRxBuffPtr) = hi2s->Instance->RXDR;
2457   hi2s->pRxBuffPtr += 2;
2458   hi2s->RxXferCount--;
2459 
2460   if (hi2s->RxXferCount == 0UL)
2461   {
2462     if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode))
2463     {
2464       /* Disable TXP, RXP, DXP, ERR interrupts */
2465       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXP | I2S_IT_RXP | I2S_IT_DXP | I2S_IT_ERR));
2466     }
2467     else
2468     {
2469       /* Disable RXP and ERR interrupt */
2470       __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXP | I2S_IT_ERR));
2471     }
2472 
2473     hi2s->State = HAL_I2S_STATE_READY;
2474     /* Call user Rx complete callback */
2475 #if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
2476     if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode))
2477     {
2478       hi2s->TxRxCpltCallback(hi2s);
2479     }
2480     else
2481     {
2482       hi2s->RxCpltCallback(hi2s);
2483     }
2484 #else
2485     if (IS_I2S_FULLDUPLEX(hi2s->Init.Mode))
2486     {
2487       HAL_I2SEx_TxRxCpltCallback(hi2s);
2488     }
2489     else
2490     {
2491       HAL_I2S_RxCpltCallback(hi2s);
2492     }
2493 #endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
2494   }
2495 }
2496 
2497 /**
2498   * @brief  This function handles I2S Communication Timeout.
2499   * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
2500   *         the configuration information for I2S module
2501   * @param  Flag Flag checked
2502   * @param  State Value of the flag expected
2503   * @param  Tickstart Tick start value
2504   * @param  Timeout Duration of the timeout
2505   * @retval HAL status
2506   */
2507 static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State,
2508                                                        uint32_t Tickstart, uint32_t Timeout)
2509 {
2510   /* Wait until flag is set to status*/
2511   while (((__HAL_I2S_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State)
2512   {
2513     if (Timeout != HAL_MAX_DELAY)
2514     {
2515       if (((HAL_GetTick() - Tickstart) >= Timeout) || (Timeout == 0UL))
2516       {
2517         /* Set the I2S State ready */
2518         hi2s->State = HAL_I2S_STATE_READY;
2519 
2520         /* Process Unlocked */
2521         __HAL_UNLOCK(hi2s);
2522 
2523         return HAL_TIMEOUT;
2524       }
2525     }
2526   }
2527   return HAL_OK;
2528 }
2529 
2530 /**
2531   * @}
2532   */
2533 
2534 /**
2535   * @}
2536   */
2537 
2538 /**
2539   * @}
2540   */
2541 
2542 #endif /* HAL_I2S_MODULE_ENABLED */
2543