/**
  * @brief  Initializes the Audio Codec audio interface (I2S)
  * @note   This function assumes that the I2S input clock (through PLL_R in 
  *         Devices RevA/Z and through dedicated PLLI2S_R in Devices RevB/Y)
  *         is already configured and ready to be used.    
  * @param  AudioFreq: Audio frequency to be configured for the I2S peripheral. 
  * @retval None
  */
static void I2S2_Init(uint32_t AudioFreq)
{
  /* Initialize the hAudioInI2s Instance parameter */
  hAudioInI2s.Instance          = I2S2;
  
  /* Disable I2S block */
  __HAL_I2S_DISABLE(&hAudioInI2s);
  
  /* I2S2 peripheral configuration */
  hAudioInI2s.Init.AudioFreq    = 2 * AudioFreq;
  hAudioInI2s.Init.ClockSource  = I2S_CLOCK_PLL;
  hAudioInI2s.Init.CPOL         = I2S_CPOL_HIGH;
  hAudioInI2s.Init.DataFormat   = I2S_DATAFORMAT_16B;
  hAudioInI2s.Init.MCLKOutput   = I2S_MCLKOUTPUT_DISABLE;
  hAudioInI2s.Init.Mode         = I2S_MODE_MASTER_RX;
  hAudioInI2s.Init.Standard     = I2S_STANDARD_LSB;
  
  /* Initialize the I2S peripheral with the structure above */
  if(HAL_I2S_GetState(&hAudioInI2s) == HAL_I2S_STATE_RESET)
  { 
    I2S2_MspInit();
  }
  
  HAL_I2S_Init(&hAudioInI2s);
}
/**
  * @brief  Initializes the Audio Codec audio interface (I2S)
  * @param  AudioFreq: Audio frequency to be configured for the I2S peripheral.
  */
static void I2SOUT_Init(uint32_t AudioFreq)
{
    /* Initialize the hAudioOutI2s Instance parameter */
    hAudioOutI2s.Instance         = I2SOUT;

    /* Disable I2S block */
    __HAL_I2S_DISABLE(&hAudioOutI2s);

    /* Perform MSP initialization at first function call */
    if(HAL_I2S_GetState(&hAudioOutI2s) == HAL_I2S_STATE_RESET)
    {
        I2SOUT_MspInit();
    }

    /* I2SOUT peripheral configuration */
    hAudioOutI2s.Init.AudioFreq   = AudioFreq;
    hAudioOutI2s.Init.CPOL        = I2S_CPOL_LOW;
    hAudioOutI2s.Init.DataFormat  = I2S_DATAFORMAT_16B;
    hAudioOutI2s.Init.MCLKOutput  = I2S_MCLKOUTPUT_ENABLE;
    hAudioOutI2s.Init.Mode        = I2S_MODE_MASTER_TX;
    hAudioOutI2s.Init.Standard    = I2S_STANDARD;

    /* Initialize the I2S peripheral with the structure above */
    HAL_I2S_Init(&hAudioOutI2s);

}
/**
  * @brief  DMA I2S communication error callback
  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
  *               the configuration information for the specified DMA module.
  * @retval None
  */
static void I2SEx_TxRxDMAError(DMA_HandleTypeDef *hdma)
{
  I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;

  /* Check if the SPI2S is disabled to edit CFG1 register */
  if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
  {
    /* Disable Rx and Tx DMA Request */
    CLEAR_BIT(hi2s->Instance->CFG1, (SPI_CFG1_RXDMAEN | SPI_CFG1_TXDMAEN));
  }
  else
  {
    /* Disable SPI peripheral */
    __HAL_I2S_DISABLE(hi2s);

    /* Disable Rx and Tx DMA Request */
    CLEAR_BIT(hi2s->Instance->CFG1, (SPI_CFG1_RXDMAEN | SPI_CFG1_TXDMAEN));

    /* Enable SPI peripheral */
    __HAL_I2S_ENABLE(hi2s);
  }

  hi2s->TxXferCount = 0U;
  hi2s->RxXferCount = 0U;

  hi2s->State= HAL_I2S_STATE_READY;

  /* Set the error code and execute error callback*/
  SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
  HAL_I2S_ErrorCallback(hi2s);
}
/**
  * @brief Resumes the audio stream playing from the Media.
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
  *         the configuration information for I2S module
  * @retval HAL status
  */
__weak HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s)
{
  /* Process Locked */
  __HAL_LOCK(hi2s);
  
  /* Disable the I2S Tx/Rx DMA requests */
  hi2s->Instance->CR2 &= ~SPI_CR2_TXDMAEN;
  hi2s->Instance->CR2 &= ~SPI_CR2_RXDMAEN;

  /* Abort the I2S DMA Stream tx */
  if(hi2s->hdmatx != NULL)
  {
    HAL_DMA_Abort(hi2s->hdmatx);
  }
  /* Abort the I2S DMA Stream rx */
  if(hi2s->hdmarx != NULL)
  {
    HAL_DMA_Abort(hi2s->hdmarx);
  }

  /* Disable I2S peripheral */
  __HAL_I2S_DISABLE(hi2s);
  
  hi2s->State = HAL_I2S_STATE_READY;
  
  /* Process Unlocked */
  __HAL_UNLOCK(hi2s);
  
  return HAL_OK;
}
Example #5
0
/**
  * @brief Resumes the audio stream playing from the Media.
  * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
  *         the configuration information for I2S module
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s)
{
  /* Process Locked */
  __HAL_LOCK(hi2s);
  
  /* Disable the I2S Tx/Rx DMA requests */
  CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
  CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
  
  /* Abort the I2S DMA Channel tx */
  if(hi2s->hdmatx != NULL)
  {
    /* Disable the I2S DMA channel */
    __HAL_DMA_DISABLE(hi2s->hdmatx);
    HAL_DMA_Abort(hi2s->hdmatx);
  }
  /* Abort the I2S DMA Channel rx */
  if(hi2s->hdmarx != NULL)
  {
    /* Disable the I2S DMA channel */
    __HAL_DMA_DISABLE(hi2s->hdmarx);
    HAL_DMA_Abort(hi2s->hdmarx);
  }

  /* Disable I2S peripheral */
  __HAL_I2S_DISABLE(hi2s);
  
  hi2s->State = HAL_I2S_STATE_READY;
  
  /* Process Unlocked */
  __HAL_UNLOCK(hi2s);
  
  return HAL_OK;
}
Example #6
0
/**
  * @brief DeInitializes the I2S peripheral
  * @param  hi2s pointer to a I2S_HandleTypeDef structure that contains
  *         the configuration information for I2S module
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_I2S_DeInit(I2S_HandleTypeDef *hi2s)
{
  /* Check the I2S handle allocation */
  if(hi2s == NULL)
  {
    return HAL_ERROR;
  }

  /* Check the parameters */
  assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));

  hi2s->State = HAL_I2S_STATE_BUSY;

  /* Disable the I2S Peripheral Clock */
  __HAL_I2S_DISABLE(hi2s);

  /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
  HAL_I2S_MspDeInit(hi2s);

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

  /* Release Lock */
  __HAL_UNLOCK(hi2s);

  return HAL_OK;
}
/**
  * @brief  Initializes the Audio Codec audio interface (I2S)
  * @param  AudioFreq: Audio frequency to be configured for the I2S peripheral. 
  * @retval AUDIO_StatusTypeDef AUDIO Status
  */
static AUDIO_StatusTypeDef I2Sx_Init(uint32_t AudioFreq)
{
  /* I2S peripheral configuration */
  hAudioOutI2s.Init.AudioFreq   = AudioFreq;
  hAudioOutI2s.Init.ClockSource = I2S_CLOCK_SYSCLK;
  hAudioOutI2s.Init.CPOL        = I2S_CPOL_LOW;
  hAudioOutI2s.Init.DataFormat  = I2S_DATAFORMAT_16B;
  hAudioOutI2s.Init.MCLKOutput  = I2S_MCLKOUTPUT_ENABLE;
  hAudioOutI2s.Init.Mode        = I2S_MODE_MASTER_TX;
  hAudioOutI2s.Init.Standard    = I2S_STANDARD;
  hAudioOutI2s.Instance         = I2Sx;

  /* Disable I2S block */
  __HAL_I2S_DISABLE(&hAudioOutI2s);

  /* Initialize the I2S peripheral with the structure above */
  if(HAL_I2S_GetState(&hAudioOutI2s) == HAL_I2S_STATE_RESET)
  { 
    I2Sx_MspInit();
  }

  if (HAL_I2S_Init(&hAudioOutI2s) != HAL_OK)
  {
    return AUDIO_ERROR;
  }
  
  return AUDIO_OK;
}
/**
  * @brief  Initializes the Audio Codec audio interface (I2S).
  * @param  AudioFreq: Audio frequency to be configured for the I2S peripheral. 
  * @retval None
  */
static void I2Sx_Init(uint32_t AudioFreq)
{
  /* Initialize the haudio_i2s Instance parameter */
  haudio_i2s.Instance = AUDIO_I2Sx;

 /* Disable I2S block */
  __HAL_I2S_DISABLE(&haudio_i2s);  

  haudio_i2s.Init.Mode = I2S_MODE_MASTER_TX;
  haudio_i2s.Init.Standard = I2S_STANDARD;
  haudio_i2s.Init.DataFormat = I2S_DATAFORMAT_16B;
  haudio_i2s.Init.AudioFreq = AudioFreq;
  haudio_i2s.Init.CPOL = I2S_CPOL_LOW;
  haudio_i2s.Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE;

  if(HAL_I2S_GetState(&haudio_i2s) == HAL_I2S_STATE_RESET)
  { 
    I2Sx_MspInit();
  }
  /* Init the I2S */
  HAL_I2S_Init(&haudio_i2s); 
}
/**
  * @brief  DMA I2S transmit receive process complete callback 
  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
  *         the configuration information for the specified DMA module.
  * @retval None
  */
static void I2SEx_DMATxRxCplt(DMA_HandleTypeDef *hdma)
{
  I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;

  if(((((DMA_Stream_TypeDef *)hdma->Instance)->CR) & DMA_SxCR_CIRC) == 0U)
  {
    /* Check if the SPI2S is disabled to edit CFG1 register */
    if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
    {
      /* Disable Tx/Rx DMA Request */
      CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN | SPI_CFG1_TXDMAEN);
    }
    else
    {
      /* Disable SPI peripheral */
      __HAL_I2S_DISABLE(hi2s);
  
      /* Disable Rx DMA Request */
      CLEAR_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN | SPI_CFG1_TXDMAEN);
  
      /* Enable SPI peripheral */
      __HAL_I2S_ENABLE(hi2s);
    }

    hi2s->TxXferCount = 0U;
    hi2s->RxXferCount = 0U;
    hi2s->State = HAL_I2S_STATE_READY;

    if (hi2s->ErrorCode != HAL_I2S_ERROR_NONE)
    {
      HAL_I2S_ErrorCallback(hi2s);
      return;
    }
  }
  HAL_I2SEx_TxRxCpltCallback(hi2s);
}
void i2s_init()
{
  MEMS_MICRO_CLK_ENABLE();

  /* Initialize the hAudioInI2s Instance parameter */
  hMemsMicro.Instance          = MEMS_MICRO_I2S;

  /* Disable I2S block */
  __HAL_I2S_DISABLE(&hMemsMicro);

  /* I2S2 peripheral configuration */
  hMemsMicro.Init.AudioFreq    = I2S_AUDIOFREQ_48K;
  hMemsMicro.Init.ClockSource  = I2S_CLOCK_PLL;
  hMemsMicro.Init.CPOL         = I2S_CPOL_HIGH;
  hMemsMicro.Init.DataFormat   = I2S_DATAFORMAT_16B;
  hMemsMicro.Init.MCLKOutput   = I2S_MCLKOUTPUT_DISABLE;
  hMemsMicro.Init.Mode         = I2S_MODE_MASTER_RX;
  hMemsMicro.Init.Standard     = I2S_STANDARD_LSB;

  mems_micro_gpio_init();
  mems_micro_dma_init();

  assert(HAL_I2S_Init(&hMemsMicro) == HAL_OK);
}
/**
  * @brief  Transmit and 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  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.
  * @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)
{
  /* 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);

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

    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 << 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 the I2S Rx DMA Half transfert complete callback */
    hi2s->hdmarx->XferHalfCpltCallback = I2SEx_DMATxRxHalfCplt;

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

    /* Set the DMA error callback */
    hi2s->hdmarx->XferErrorCallback = I2SEx_TxRxDMAError;

    /* Enable the Rx DMA Channel */
    HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->RXDR, (uint32_t)hi2s->pRxBuffPtr, hi2s->RxXferSize);

    /* Check if the I2S Rx requests are already enabled */ 
    if(HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN))
    {
      /* Check if the SPI2S is disabled to edit CFG1 register */
      if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
      {
        /* Enable Rx DMA Request */
        SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);
      }
      else
      {
        /* Disable SPI peripheral */
        __HAL_I2S_DISABLE(hi2s);
    
        /* Enable Rx DMA Request */
        SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN);

        /* Enable SPI peripheral */
        __HAL_I2S_ENABLE(hi2s);
      }
    }

    /* Set the I2S Tx DMA transfer callbacks as NULL because the communication closing
    is performed in DMA reception callbacks */
    hi2s->hdmatx->XferHalfCpltCallback = NULL;
    hi2s->hdmatx->XferCpltCallback     = NULL;
    hi2s->hdmatx->XferErrorCallback    = NULL;

    /* Enable the Tx DMA Channel */
    HAL_DMA_Start_IT(hi2s->hdmatx, (uint32_t)hi2s->pTxBuffPtr, (uint32_t)&hi2s->Instance->TXDR, hi2s->TxXferSize);

    /* Check if the I2S Tx requests are already enabled */ 
    if(HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN))
    {
      /* Check if the SPI2S is disabled to edit CFG1 register */
      if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
      {
        /* Enable Tx DMA Request */
        SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);
      }
      else
      {
        /* Disable SPI peripheral */
        __HAL_I2S_DISABLE(hi2s);
    
        /* Enable Tx/Rx DMA Request */
        SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN);

        /* Enable SPI peripheral */
        __HAL_I2S_ENABLE(hi2s);
      }
    }

    /* Process Unlocked */
    __HAL_UNLOCK(hi2s);

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