Ejemplo n.º 1
0
/**
  * @brief Receive an amount of data in non-blocking mode with Interrupt
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
  *         the configuration information for I2S module
  * @retval HAL status
  */
static HAL_StatusTypeDef I2S_Receive_IT(I2S_HandleTypeDef *hi2s)
{
  if(hi2s->State == HAL_I2S_STATE_BUSY_RX)
  {
    /* Receive data */
    (*hi2s->pRxBuffPtr++) = hi2s->Instance->DR;

    hi2s->RxXferCount--;

    /* Check if Master Receiver mode is selected */
    if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
    {
      /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
      access to the SPI_SR register. */ 
      __HAL_I2S_CLEAR_OVRFLAG(hi2s);
    }

    if(hi2s->RxXferCount == 0)
    {
      /* Disable RXNE and ERR interrupt */
      __HAL_I2S_DISABLE_IT(hi2s, (uint32_t)(I2S_IT_RXNE | I2S_IT_ERR));

      hi2s->State = HAL_I2S_STATE_READY;

      HAL_I2S_RxCpltCallback(hi2s);
    }

    return HAL_OK; 
  }
  else
  {
    return HAL_BUSY; 
  } 
}
Ejemplo n.º 2
0
/**
  * @brief  This function handles I2S interrupt request.
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
  *         the configuration information for I2S module
  * @retval None
  */
__weak void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s)
{  
  uint32_t tmp1 = 0, tmp2 = 0; 

    if(hi2s->State == HAL_I2S_STATE_BUSY_RX)
    {
      tmp1 = __HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_RXNE);
      tmp2 = __HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_RXNE);
      /* I2S in mode Receiver ------------------------------------------------*/
      if((tmp1 != RESET) && (tmp2 != RESET))
      {
        I2S_Receive_IT(hi2s);
      }

      tmp1 = __HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR);
      tmp2 = __HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR);
      /* I2S Overrun error interrupt occurred ---------------------------------*/
      if((tmp1 != RESET) && (tmp2 != RESET))
      {
        __HAL_I2S_CLEAR_OVRFLAG(hi2s);
        hi2s->ErrorCode |= HAL_I2S_ERROR_OVR;
      }
    }

    if(hi2s->State == HAL_I2S_STATE_BUSY_TX)
    {
      tmp1 = __HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_TXE);
      tmp2 = __HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_TXE);
      /* I2S in mode Transmitter -----------------------------------------------*/
      if((tmp1 != RESET) && (tmp2 != RESET))
      {
        I2S_Transmit_IT(hi2s);
      }

      tmp1 = __HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR);
      tmp2 = __HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR);
      /* I2S Underrun error interrupt occurred --------------------------------*/
      if((tmp1 != RESET) && (tmp2 != RESET))
      {
        __HAL_I2S_CLEAR_UDRFLAG(hi2s);
        hi2s->ErrorCode |= HAL_I2S_ERROR_UDR;
    }
  }

  /* Call the Error call Back in case of Errors */
  if(hi2s->ErrorCode != HAL_I2S_ERROR_NONE)
  {
    /* Set the I2S state ready to be able to start again the process */
    hi2s->State= HAL_I2S_STATE_READY;
    HAL_I2S_ErrorCallback(hi2s);
  }
}
Ejemplo n.º 3
0
/**
  * @brief Receive an amount of data in non-blocking mode with DMA 
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
  *         the configuration information for I2S module
  * @param pData: a 16-bit pointer to the Receive data buffer.
  * @param Size: number of data sample to be sent:
  * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
  *       configuration phase, the Size parameter means the number of 16-bit data length 
  *       in the transaction and when a 24-bit data frame or a 32-bit data frame is selected 
  *       the Size parameter means the number of 16-bit data length. 
  * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization 
  *       between Master and Slave(example: audio streaming).
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
{
  uint32_t *tmp;
  uint32_t tmp1 = 0, tmp2 = 0;  
  
  if((pData == NULL) || (Size == 0))
  {
    return  HAL_ERROR;
  }

  if(hi2s->State == HAL_I2S_STATE_READY)
  {
    hi2s->pRxBuffPtr = pData;
    tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
    tmp2 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
    if((tmp1 == I2S_DATAFORMAT_24B)|| \
      (tmp2 == I2S_DATAFORMAT_32B))
    {
      hi2s->RxXferSize = Size*2;
      hi2s->RxXferCount = Size*2;
    }
    else
    {
      hi2s->RxXferSize = Size;
      hi2s->RxXferCount = Size;
    }
    /* Process Locked */
    __HAL_LOCK(hi2s);
    
    hi2s->State = HAL_I2S_STATE_BUSY_RX;
    hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
    
    /* Set the I2S Rx DMA Half transfer complete callback */
    hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt;
    
    /* Set the I2S Rx DMA transfer complete callback */
    hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt;
    
    /* Set the DMA error callback */
    hi2s->hdmarx->XferErrorCallback = I2S_DMAError;
    
    /* Check if Master Receiver mode is selected */
    if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
    {
      /* Clear the Overrun Flag by a read operation to the SPI_DR register followed by a read
      access to the SPI_SR register. */ 
      __HAL_I2S_CLEAR_OVRFLAG(hi2s);
    }
    
    /* Enable the Rx DMA Stream */
    tmp = (uint32_t*)&pData;
    HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, *(uint32_t*)tmp, hi2s->RxXferSize);
    
    /* Check if the I2S is already enabled */ 
    if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
    {
      /* Enable I2S peripheral */
      __HAL_I2S_ENABLE(hi2s);
    }

     /* Check if the I2S Rx request is already enabled */ 
    if((hi2s->Instance->CR2 &SPI_CR2_RXDMAEN) != SPI_CR2_RXDMAEN)
    {
      /* Enable Rx DMA Request */  
      hi2s->Instance->CR2 |= SPI_CR2_RXDMAEN;
    }

    /* Process Unlocked */
    __HAL_UNLOCK(hi2s);

    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}
Ejemplo n.º 4
0
/**
  * @brief Receive an amount of data in blocking mode 
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
  *         the configuration information for I2S module
  * @param pData: a 16-bit pointer to data buffer.
  * @param Size: number of data sample to be sent:
  * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
  *       configuration phase, the Size parameter means the number of 16-bit data length 
  *       in the transaction and when a 24-bit data frame or a 32-bit data frame is selected 
  *       the Size parameter means the number of 16-bit data length. 
  * @param Timeout: Timeout duration
  * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization 
  *       between Master and Slave(example: audio streaming).
  * @note In I2S Master Receiver mode, just after enabling the peripheral the clock will be generate
  *       in continuous way and as the I2S is not disabled at the end of the I2S transaction.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
{
  uint32_t tmp1 = 0, tmp2 = 0;   
  if((pData == NULL ) || (Size == 0)) 
  {
    return  HAL_ERROR;
  }
  
  if(hi2s->State == HAL_I2S_STATE_READY)
  { 
    tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
    tmp2 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
    if((tmp1 == I2S_DATAFORMAT_24B)|| \
       (tmp2 == I2S_DATAFORMAT_32B))
    {
      hi2s->RxXferSize = Size*2;
      hi2s->RxXferCount = Size*2;
    }
    else
    {
      hi2s->RxXferSize = Size;
      hi2s->RxXferCount = Size;
    }
    /* Process Locked */
    __HAL_LOCK(hi2s);

    hi2s->State = HAL_I2S_STATE_BUSY_RX;

    /* Check if the I2S is already enabled */ 
    if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
    {
      /* Enable I2S peripheral */
      __HAL_I2S_ENABLE(hi2s);
    }

    /* Check if Master Receiver mode is selected */
    if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
    {
      /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
      access to the SPI_SR register. */ 
      __HAL_I2S_CLEAR_OVRFLAG(hi2s);
    }

    /* Receive data */
    while(hi2s->RxXferCount > 0)
    {
      /* Wait until RXNE flag is set */
      if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, RESET, Timeout) != HAL_OK)
      {
        return HAL_TIMEOUT;
      }

      (*pData++) = hi2s->Instance->DR;
      hi2s->RxXferCount--;
    }

    hi2s->State = HAL_I2S_STATE_READY; 
    
    /* Process Unlocked */
    __HAL_UNLOCK(hi2s);
    
    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}
/**
  * @brief Receive an amount of data in blocking mode 
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
  *         the configuration information for I2S module
  * @param pData: a 16-bit pointer to data buffer.
  * @param Size: number of data sample to be sent:
  * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
  *       configuration phase, the Size parameter means the number of 16-bit data length 
  *       in the transaction and when a 24-bit data frame or a 32-bit data frame is selected 
  *       the Size parameter means the number of 16-bit data length. 
  * @param Timeout: Timeout duration
  * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization 
  *       between Master and Slave(example: audio streaming).
  * @note In I2S Master Receiver mode, just after enabling the peripheral the clock will be generate
  *       in continouse way and as the I2S is not disabled at the end of the I2S transaction.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
{
  if((pData == NULL ) || (Size == 0)) 
  {
    return  HAL_ERROR;                                    
  }
  
  if(hi2s->State == HAL_I2S_STATE_READY)
  { 
    if(((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
       ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B))
    {
      hi2s->RxXferSize = (Size << 1);
      hi2s->RxXferCount = (Size << 1);
    }
    else
    {
      hi2s->RxXferSize = Size;
      hi2s->RxXferCount = Size;
    }
    /* Process Locked */
    __HAL_LOCK(hi2s);
    
    hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
    hi2s->State = HAL_I2S_STATE_BUSY_RX;
        
    /* Check if the I2S is already enabled */ 
    if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
    {
      /* Enable I2S peripheral */    
      __HAL_I2S_ENABLE(hi2s);
    }
    
    /* Check if Master Receiver mode is selected */
    if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
    {
      /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
      access to the SPI_SR register. */ 
      __HAL_I2S_CLEAR_OVRFLAG(hi2s);        
    }
    
    /* Receive data */
    while(hi2s->RxXferCount > 0)
    {
      /* Wait until RXNE flag is set */
      if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout) != HAL_OK) 
      {
        /* Set the error code and execute error callback*/
        hi2s->ErrorCode |= HAL_I2S_ERROR_TIMEOUT;
        HAL_I2S_ErrorCallback(hi2s);
        return HAL_TIMEOUT;
      }
      
      /* Check if an overrun occurs */
      if(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET) 
      {
        /* Set the I2S State ready */
        hi2s->State = HAL_I2S_STATE_READY; 

        /* Process Unlocked */
        __HAL_UNLOCK(hi2s);

        /* Set the error code and execute error callback*/
        hi2s->ErrorCode |= HAL_I2S_ERROR_OVR;
        HAL_I2S_ErrorCallback(hi2s);

        return HAL_ERROR;
      }

      (*pData++) = hi2s->Instance->DR;
      hi2s->RxXferCount--;
    }      

    hi2s->State = HAL_I2S_STATE_READY; 
    
    /* Process Unlocked */
    __HAL_UNLOCK(hi2s);
    
    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}
/**
  * @brief Full-Duplex Transmit/Receive data in non-blocking mode using DMA  
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
  *         the configuration information for I2S module
  * @param pTxData: a 16-bit pointer to the Transmit data buffer.
  * @param pRxData: a 16-bit pointer to the Receive data buffer.
  * @param Size: number of data sample to be sent:
  * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
  *       configuration phase, the Size parameter means the number of 16-bit data length 
  *       in the transaction and when a 24-bit data frame or a 32-bit data frame is selected 
  *       the Size parameter means the number of 16-bit data length. 
  * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization 
  *       between Master and Slave(example: audio streaming).
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size)
{
  uint32_t *tmp;
  uint32_t tmp1 = 0, tmp2 = 0;
    
  if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0)) 
  {
    return  HAL_ERROR;
  }

  if(hi2s->State == HAL_I2S_STATE_READY)
  {
    hi2s->pTxBuffPtr = pTxData;
    hi2s->pRxBuffPtr = pRxData;

    tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
    tmp2 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
    /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended 
       is selected during the I2S configuration phase, the Size parameter means the number
       of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data 
       frame is selected the Size parameter means the number of 16-bit data length. */
    if((tmp1 == I2S_DATAFORMAT_24B)||\
       (tmp2 == I2S_DATAFORMAT_32B))
    {
      hi2s->TxXferSize = Size*2;
      hi2s->TxXferCount = Size*2;
      hi2s->RxXferSize = Size*2;
      hi2s->RxXferCount = Size*2;
    }
    else
    {
      hi2s->TxXferSize = Size;
      hi2s->TxXferCount = Size;
      hi2s->RxXferSize = Size;
      hi2s->RxXferCount = Size;
    }

    /* Process Locked */
    __HAL_LOCK(hi2s);

    hi2s->State = HAL_I2S_STATE_BUSY_TX_RX;
    hi2s->ErrorCode = HAL_I2S_ERROR_NONE;

    /* Set the I2S Rx DMA Half transfert complete callback */
    hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt;

    /* Set the I2S Rx DMA transfert complete callback */
    hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt;

    /* Set the I2S Rx DMA error callback */
    hi2s->hdmarx->XferErrorCallback = I2S_DMAError;

    /* Set the I2S Tx DMA Half transfert complete callback */
    hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt;

    /* Set the I2S Tx DMA transfert complete callback */
    hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt;

    /* Set the I2S Tx DMA error callback */
    hi2s->hdmatx->XferErrorCallback = I2S_DMAError;

    tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
    tmp2 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
    /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */
    if((tmp1 == I2S_MODE_MASTER_TX) || (tmp2 == I2S_MODE_SLAVE_TX))
    {
      /* Enable the Rx DMA Stream */
      tmp = (uint32_t*)&pRxData;
      HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&I2SxEXT(hi2s->Instance)->DR, *(uint32_t*)tmp, hi2s->RxXferSize);

      /* Enable Rx DMA Request */  
      I2SxEXT(hi2s->Instance)->CR2 |= SPI_CR2_RXDMAEN;

      /* Enable the Tx DMA Stream */
      tmp = (uint32_t*)&pTxData;
      HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t*)tmp, (uint32_t)&hi2s->Instance->DR, hi2s->TxXferSize);

      /* Enable Tx DMA Request */  
      hi2s->Instance->CR2 |= SPI_CR2_TXDMAEN;

      /* Check if the I2S is already enabled */ 
      if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
      {
        /* Enable I2Sext(receiver) before enabling I2Sx peripheral */
        I2SxEXT(hi2s->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE;

        /* Enable I2S peripheral after the I2Sext */
        __HAL_I2S_ENABLE(hi2s);
      }
    }
    else
    {
      /* Enable the Tx DMA Stream */
      tmp = (uint32_t*)&pTxData;
      HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t*)tmp, (uint32_t)&I2SxEXT(hi2s->Instance)->DR, hi2s->TxXferSize);

      /* Enable Tx DMA Request */  
      I2SxEXT(hi2s->Instance)->CR2 |= SPI_CR2_TXDMAEN;

      /* Enable the Rx DMA Stream */
      tmp = (uint32_t*)&pRxData;
      HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, *(uint32_t*)tmp, hi2s->RxXferSize);

      /* Enable Rx DMA Request */  
      hi2s->Instance->CR2 |= SPI_CR2_RXDMAEN;

      /* Check if the I2S is already enabled */ 
      if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
      {
        /* Enable I2S peripheral before the I2Sext */
        __HAL_I2S_ENABLE(hi2s);

        /* Enable I2Sext(transmitter) after enabling I2Sx peripheral */
        I2SxEXT(hi2s->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE;
      }
      else
      {
        /* Check if Master Receiver mode is selected */
        if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
        {
          /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
          access to the SPI_SR register. */ 
          __HAL_I2S_CLEAR_OVRFLAG(hi2s);
        }
      }
    }

    /* Process Unlocked */
    __HAL_UNLOCK(hi2s);

    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}
/**
  * @brief Full-Duplex Transmit/Receive data in blocking mode.
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
  *         the configuration information for I2S module
  * @param pTxData: a 16-bit pointer to the Transmit data buffer.
  * @param pRxData: a 16-bit pointer to the Receive data buffer.
  * @param Size: number of data sample to be sent:
  * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
  *       configuration phase, the Size parameter means the number of 16-bit data length 
  *       in the transaction and when a 24-bit data frame or a 32-bit data frame is selected 
  *       the Size parameter means the number of 16-bit data length. 
  * @param Timeout: Timeout duration
  * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization 
  *       between Master and Slave(example: audio streaming).
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_I2SEx_TransmitReceive(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size, uint32_t Timeout)
{
  uint32_t tickstart = 0;
  uint32_t tmp1 = 0, tmp2 = 0;
 
  if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0)) 
  {
    return  HAL_ERROR;
  }

  /* Check the I2S State */
  if(hi2s->State == HAL_I2S_STATE_READY)
  {  
    tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
    tmp2 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); 
    /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended 
       is selected during the I2S configuration phase, the Size parameter means the number
       of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data 
       frame is selected the Size parameter means the number of 16-bit data length. */
    if((tmp1 == I2S_DATAFORMAT_24B)|| \
       (tmp2 == I2S_DATAFORMAT_32B))
    {
      hi2s->TxXferSize = Size*2;
      hi2s->TxXferCount = Size*2;
      hi2s->RxXferSize = Size*2;
      hi2s->RxXferCount = Size*2;
    }
    else
    {
      hi2s->TxXferSize = Size;
      hi2s->TxXferCount = Size;
      hi2s->RxXferSize = Size;
      hi2s->RxXferCount = Size;
    }
    
    /* Process Locked */
    __HAL_LOCK(hi2s);
    
    /* Set the I2S State busy TX/RX */
    hi2s->State = HAL_I2S_STATE_BUSY_TX_RX;
    
    tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
    tmp2 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
    /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */
    if((tmp1 == I2S_MODE_MASTER_TX) || (tmp2 == I2S_MODE_SLAVE_TX))
    { 
      /* Check if the I2S is already enabled: The I2S is kept enabled at the end of transaction
      to avoid the clock de-synchronization between Master and Slave. */ 
      if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
      {
        /* Enable I2Sext(receiver) before enabling I2Sx peripheral */
        I2SxEXT(hi2s->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE;

        /* Enable I2Sx peripheral */
        __HAL_I2S_ENABLE(hi2s);
      }
      
      while(hi2s->TxXferCount > 0)
      {
        /* Wait until TXE flag is set */
        if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, RESET, Timeout) != HAL_OK)
        {
          return HAL_TIMEOUT;
        }
        hi2s->Instance->DR = (*pTxData++);

        /* Get tick */
        tickstart = HAL_GetTick();

        /* Wait until RXNE flag is set */
        while((I2SxEXT(hi2s->Instance)->SR & SPI_SR_RXNE) != SPI_SR_RXNE)
        {
          if(Timeout != HAL_MAX_DELAY)
          {
            if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
            {
              /* Process Unlocked */
              __HAL_UNLOCK(hi2s);

              return HAL_TIMEOUT;
            }
          }
        }
        (*pRxData++) = I2SxEXT(hi2s->Instance)->DR;
        
        hi2s->TxXferCount--;
        hi2s->RxXferCount--;
      }
    }
    /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */
    else
    {
      /* Check if the I2S is already enabled */ 
      if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
      {
        /* Enable I2S peripheral before the I2Sext*/
        __HAL_I2S_ENABLE(hi2s);

        /* Enable I2Sext(transmitter) after enabling I2Sx peripheral */
        I2SxEXT(hi2s->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE;
      }
      else
      {
        /* Check if Master Receiver mode is selected */
        if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
        {
          /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
          access to the SPI_SR register. */ 
          __HAL_I2S_CLEAR_OVRFLAG(hi2s);
        }
      }
      while(hi2s->TxXferCount > 0)
      {
        /* Get tick */
        tickstart = HAL_GetTick();

        /* Wait until TXE flag is set */
        while((I2SxEXT(hi2s->Instance)->SR & SPI_SR_TXE) != SPI_SR_TXE)
        {
          if(Timeout != HAL_MAX_DELAY)
          {
            if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
            {
              /* Process Unlocked */
              __HAL_UNLOCK(hi2s);

              return HAL_TIMEOUT;
            }
          }
        }
        I2SxEXT(hi2s->Instance)->DR = (*pTxData++);
        
        /* Wait until RXNE flag is set */
        if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, RESET, Timeout) != HAL_OK)
        {
          return HAL_TIMEOUT;
        }
        (*pRxData++) = hi2s->Instance->DR;

        hi2s->TxXferCount--;
        hi2s->RxXferCount--;
      }
    }

    /* Set the I2S State ready */
    hi2s->State = HAL_I2S_STATE_READY; 

    /* Process Unlocked */
    __HAL_UNLOCK(hi2s);
    
    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}