Пример #1
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);
  }
}
Пример #2
0
/**
  * @brief This function handles I2S Communication Timeout.
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
  *         the configuration information for I2S module
  * @param Flag: Flag checked
  * @param Status: Value of the flag expected
  * @param Timeout: Duration of the timeout
  * @retval HAL status
  */
HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, uint32_t Status, uint32_t Timeout)
{
  uint32_t tickstart = 0;
  
  /* Get tick */
  tickstart = HAL_GetTick();
  
  /* Wait until flag is set */
  if(Status == RESET)
  {
    while(__HAL_I2S_GET_FLAG(hi2s, Flag) == RESET)
    {
      if(Timeout != HAL_MAX_DELAY)
      {
        if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
        {
          /* Set the I2S State ready */
          hi2s->State= HAL_I2S_STATE_READY;

          /* Process Unlocked */
          __HAL_UNLOCK(hi2s);

          return HAL_TIMEOUT;
        }
      }
    }
  }
  else
  {
    while(__HAL_I2S_GET_FLAG(hi2s, Flag) != RESET)
    {
      if(Timeout != HAL_MAX_DELAY)
      {
        if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
        {
          /* Set the I2S State ready */
          hi2s->State= HAL_I2S_STATE_READY;

          /* Process Unlocked */
          __HAL_UNLOCK(hi2s);

          return HAL_TIMEOUT;
        }
      }
    }
  }
  return HAL_OK;
}
/**
  * @brief This function handles I2S Communication Timeout.
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
  *         the configuration information for I2S module
  * @param Flag: Flag checked
  * @param State: Value of the flag expected
  * @param Timeout: Duration of the timeout
  * @retval HAL status
  */
static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, 
                                                       uint32_t State, uint32_t Timeout)
{
  uint32_t tickstart = HAL_GetTick();
     
  while((__HAL_I2S_GET_FLAG(hi2s, Flag)) != State)
  {
    if(Timeout != HAL_MAX_DELAY)
    {
    	if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
      {
        /* Set the I2S State ready */
        hi2s->State= HAL_I2S_STATE_READY;
      
        /* Process Unlocked */
        __HAL_UNLOCK(hi2s);
      
        return HAL_TIMEOUT;
      }
    }
  }
  
  return HAL_OK;      
}
Пример #4
0
/**
  * @brief  Transmit and 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  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 frames to be sent
  * @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   This function can use an Audio Frequency up to 48KHz when I2S Clock Source is 32MHz
  * @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 = 0U;
  uint32_t isDataFormat16B = 2U;

  /* Check Mode parameter */
  assert_param(IS_I2S_FD_MODE(hi2s->Init.Mode));

  if((pTxData == NULL ) || (Size == 0U))
  {
    return  HAL_ERROR;
  }

  /* Process Locked */
  __HAL_LOCK(hi2s);

  /* Init tickstart for timeout management*/
  tickstart = HAL_GetTick();

  if(hi2s->State == HAL_I2S_STATE_READY)
  {
    /* Check the Data Format value */
    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))
    {
      isDataFormat16B = 0U;
    }
    else
    {
      isDataFormat16B = 1U;
    }

    if(!isDataFormat16B)
    {
      hi2s->TxXferSize  = (Size << 1U);
      hi2s->TxXferCount = (Size << 1U);

      hi2s->RxXferSize  = (Size << 1U);
      hi2s->RxXferCount = (Size << 1U);
    }
    else
    {
      hi2s->TxXferSize  = Size;
      hi2s->TxXferCount = Size;

      hi2s->RxXferSize  = Size;
      hi2s->RxXferCount = Size;
    }

    /* Set state and reset error code */
    hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
    hi2s->State = HAL_I2S_STATE_BUSY_TX_RX;
    hi2s->pTxBuffPtr = pTxData;
    hi2s->pRxBuffPtr = pRxData;

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

    if(IS_I2S_MASTER(hi2s->Init.Mode))
    {
      hi2s->Instance->CR1 |= SPI_CR1_CSTART;
    }

    /* Transmit and Receive data in 32 Bit mode */
    if (!isDataFormat16B)
    {
      while ((hi2s->TxXferCount > 0U) || (hi2s->RxXferCount > 0U))
      {
        /* Check TXE flag */
        if ((hi2s->TxXferCount > 0U) && (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_TXE)))
        {
          *((__IO uint32_t *)&hi2s->Instance->TXDR) = *((uint32_t *)hi2s->pTxBuffPtr);
          hi2s->pTxBuffPtr += sizeof(uint32_t);
          hi2s->TxXferCount --;
        }
  
        /* Check RXNE flag */
        if ((hi2s->RxXferCount > 0U) && (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_RXNE)))
        {
          *((uint32_t *)hi2s->pRxBuffPtr) = *((__IO uint32_t *)&hi2s->Instance->RXDR);
          hi2s->pRxBuffPtr += sizeof(uint32_t);
          hi2s->RxXferCount --;
        }

        /* Timeout Management */
        if ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick() - tickstart) >=  Timeout))
        {
          /* Set the error code and execute error callback*/
          SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
          HAL_I2S_ErrorCallback(hi2s);

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

          /* Process Unlocked */
          __HAL_UNLOCK(hi2s);
          return HAL_ERROR;
        }
      }
    }
    /* Transmit and Receive data in 16 Bit mode */
    else 
    {
      while ((hi2s->TxXferCount > 0U) || (hi2s->RxXferCount > 0U))
      {
        /* Check TXE flag */
        if ((hi2s->TxXferCount > 0U) && (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_TXE)))
        {
          if ( (hi2s->TxXferCount > 1U) && (hi2s->Init.FifoThreshold > SPI_FIFO_THRESHOLD_01DATA))
          {
            *((__IO uint32_t *)&hi2s->Instance->TXDR) = *((uint32_t *)hi2s->pTxBuffPtr);
            hi2s->pTxBuffPtr += sizeof(uint32_t);
            hi2s->TxXferCount-=2;
          }
          else
          {
            *((__IO uint16_t *)&hi2s->Instance->TXDR) = *((uint16_t *)hi2s->pTxBuffPtr);
            hi2s->pTxBuffPtr += sizeof(uint16_t);
            hi2s->TxXferCount--;
          }
        }

        /* Check RXNE flag */
        if ((hi2s->RxXferCount > 0U) && (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_RXNE)))
        {
          if (hi2s->Instance->SR & I2S_FLAG_RXWNE)
          {
            *((uint32_t *)hi2s->pRxBuffPtr) = *((__IO uint32_t *)&hi2s->Instance->RXDR);
            hi2s->pRxBuffPtr += sizeof(uint32_t);
            hi2s->RxXferCount-=2;
          }
          else
          {
            *((uint16_t *)hi2s->pRxBuffPtr) = *((__IO uint16_t *)&hi2s->Instance->RXDR);
            hi2s->pRxBuffPtr += sizeof(uint16_t);
            hi2s->RxXferCount--;
          }
        }

        /* Timeout Management */
        if ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick() - tickstart) >=  Timeout))
        {
          /* Set the error code and execute error callback*/
          SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
          HAL_I2S_ErrorCallback(hi2s);

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

          /* Process Unlocked */
          __HAL_UNLOCK(hi2s);
          return HAL_ERROR;
        }
      }
    }

    /* Wait until TXE flag is set, to confirm the end of the transaction */
    if (I2SEx_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, RESET, Timeout) != HAL_OK)
    {
      return HAL_TIMEOUT;
    }

    hi2s->State = HAL_I2S_STATE_READY;

    /* Process Unlocked */
    __HAL_UNLOCK(hi2s);

    return HAL_OK;
  }
  else
  {
    /* Process Unlocked */
    __HAL_UNLOCK(hi2s);
    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 Transmit 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).
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_I2S_Transmit(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->TxXferSize = (Size << 1);
      hi2s->TxXferCount = (Size << 1);
    }
    else
    {
      hi2s->TxXferSize = Size;
      hi2s->TxXferCount = Size;
    }
    
    /* Process Locked */
    __HAL_LOCK(hi2s);
    
    hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
    hi2s->State = HAL_I2S_STATE_BUSY_TX;
   
    /* Check if the I2S is already enabled */ 
    if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
    {
      /* Enable I2S peripheral */    
      __HAL_I2S_ENABLE(hi2s);
    }
    
    while(hi2s->TxXferCount > 0)
    {
      hi2s->Instance->DR = (*pData++);
      hi2s->TxXferCount--;   
      /* Wait until TXE flag is set */
      if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, 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 underrun occurs */
      if(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == 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_UDR;
        HAL_I2S_ErrorCallback(hi2s);

        return HAL_ERROR;
      }
    }      
    
    /* Wait until Busy flag is reset */
    if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_BSY, RESET, Timeout) != HAL_OK) 
    {
      /* Set the error code and execute error callback*/
      hi2s->ErrorCode |= HAL_I2S_ERROR_TIMEOUT;
      HAL_I2S_ErrorCallback(hi2s);
      return HAL_TIMEOUT;
    }
    
    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 Interrupt 
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
  *         the configuration information for I2S module
  * @retval HAL status
  */
HAL_StatusTypeDef I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s)
{
  uint32_t tmp1 = 0, tmp2 = 0;
  
  if(hi2s->State == HAL_I2S_STATE_BUSY_TX_RX)
  {
    /* Process Locked */
    __HAL_LOCK(hi2s);

    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))
    {
      if(hi2s->TxXferCount != 0)
      {
        if(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_TXE) != RESET)
        {        
          /* Transmit data */
          hi2s->Instance->DR = (*hi2s->pTxBuffPtr++);
          hi2s->TxXferCount--;

          if(hi2s->TxXferCount == 0)
          {
            /* Disable TXE interrupt */
            __HAL_I2S_DISABLE_IT(hi2s, I2S_IT_TXE);
          }
        }
      }

      if(hi2s->RxXferCount != 0)
      {
        if((I2SxEXT(hi2s->Instance)->SR & SPI_SR_RXNE) == SPI_SR_RXNE)
        {
          /* Receive data */
          (*hi2s->pRxBuffPtr++) = I2SxEXT(hi2s->Instance)->DR;
          hi2s->RxXferCount--;

          if(hi2s->RxXferCount == 0)
          {
            /* Disable I2Sext RXNE interrupt */
            I2SxEXT(hi2s->Instance)->CR2 &= ~I2S_IT_RXNE;
          }
        }
      }
    }
    /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */ 
    else
    {
      if(hi2s->TxXferCount != 0)
      {
        if((I2SxEXT(hi2s->Instance)->SR & SPI_SR_TXE) == SPI_SR_TXE)
        {        
          /* Transmit data */
          I2SxEXT(hi2s->Instance)->DR = (*hi2s->pTxBuffPtr++);
          hi2s->TxXferCount--;

          if(hi2s->TxXferCount == 0)
          {
            /* Disable I2Sext TXE interrupt */
            I2SxEXT(hi2s->Instance)->CR2 &= ~I2S_IT_TXE;

            HAL_I2S_TxCpltCallback(hi2s);
          }
        }
      }
      if(hi2s->RxXferCount != 0)
      {
        if(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_RXNE) != RESET)
        {
          /* Receive data */
          (*hi2s->pRxBuffPtr++) = hi2s->Instance->DR;
          hi2s->RxXferCount--;

          if(hi2s->RxXferCount == 0)
          {
            /* Disable RXNE interrupt */
            __HAL_I2S_DISABLE_IT(hi2s, I2S_IT_RXNE);

            HAL_I2S_RxCpltCallback(hi2s);
          }
        }
      }
    }

    tmp1 = hi2s->RxXferCount;
    tmp2 = hi2s->TxXferCount;
    if((tmp1 == 0) && (tmp2 == 0))
    {
      /* Disable I2Sx ERR interrupt */
      __HAL_I2S_DISABLE_IT(hi2s, I2S_IT_ERR);
      /* Disable I2Sext ERR interrupt */
      I2SxEXT(hi2s->Instance)->CR2 &= ~I2S_IT_ERR;
      
      hi2s->State = HAL_I2S_STATE_READY; 
    }

    /* Process Unlocked */
    __HAL_UNLOCK(hi2s);

    return HAL_OK;
  }
  else
  {
    return HAL_BUSY; 
  }
}
Пример #8
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 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;
  }
  
  /* Process Locked */
  __HAL_LOCK(hi2s);
  
  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;
    }
        
    /* Set state and reset error code */
    hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
    hi2s->State = HAL_I2S_STATE_BUSY_RX;
    hi2s->pRxBuffPtr = pData;
    
    /* Check if the I2S is already enabled */ 
    if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
    {
      /* Enable I2S peripheral */
      __HAL_I2S_ENABLE(hi2s);
    }
     
    /* Receive data */
    while(hi2s->RxXferCount > 0)
    {
      /* Wait until RXNE flag is reset */
      if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, RESET, Timeout) != HAL_OK)
      {
        return HAL_TIMEOUT;
      }
      
      (*hi2s->pRxBuffPtr++) = hi2s->Instance->DR;
      hi2s->RxXferCount--;

      /* 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;
        return HAL_ERROR;
      }
    }
    
    hi2s->State = HAL_I2S_STATE_READY; 
    
    /* Process Unlocked */
    __HAL_UNLOCK(hi2s);
    
    return HAL_OK;
  }
  else
  {
    /* Process Unlocked */
    __HAL_UNLOCK(hi2s);
    return HAL_BUSY;
  }
}