/**
  ******************************************************************************
  * @file    stm8l15x_aes.c
  * @author  MCD Application Team
  * @version V1.4.0
  * @date    09/24/2010
  * @brief   This file provides all the AES firmware functions.
  ******************************************************************************
  * @copy
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2>
  */

/* Includes ------------------------------------------------------------------*/
#include "stm8l15x_aes.h"

/** @addtogroup STM8L15x_StdPeriph_Driver
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Public functions ----------------------------------------------------------*/

/** @}
  * @addtogroup AES_Public_Functions
  * @{
  */

/**
  * @brief   Deinitializes the AES peripheral.
  * @param   None.
  * @retval  None
  */
void AES_DeInit(void)
{
  /* Set AES_CR to reset value 0x00, AES_SR is reset by setting ERRC and CCFC bits in CR */
  AES->CR = AES_CR_ERRC | AES_CR_CCFC;
  AES->DINR = AES_DINR_RESET_VALUE;       /* Set AES_DINR to reset value 0x00 */
  AES->DOUTR = AES_DOUTR_RESET_VALUE;     /* Set AES_DOUTR to reset value 0x00 */
}

/**
  * @brief   Configures the AES operation mode.
  * @param   AES_Operation : the selected AES operation mode.
  *          This parameter can be any of the @ref AES_Operation_TypeDef
  *          enumeration.
  * @retval  None
  */
void AES_Config(AES_Operation_TypeDef AES_Operation)
{
  /* Check the parameter */
  assert_param(IS_AES_MODE(AES_Operation));

  /* Reset the operaton mode bits in CR register */
  AES->CR &= (uint8_t) (~AES_CR_MODE);

  /* Set the new operaton mode bits in CR register */
  AES->CR |= (uint8_t) (AES_Operation);
}

/**
  * @brief  Enable the AES peripheral.
  * @param  NewState : The new state of the AES peripheral.
  *         This parameter can be any of the @ref FunctionalState enumeration.
  * @retval None
  */
void AES_Cmd(FunctionalState NewState)
{
  /* Check the parameter */
  assert_param(IS_FUNCTIONAL_STATE(NewState));

  if (NewState != DISABLE)
  {
    AES->CR |= (uint8_t) AES_CR_EN;   /**< AES Enable */
  }
  else
  {
    AES->CR &= (uint8_t)(~AES_CR_EN);  /**< AES Disable */
  }
}

/**
  * @brief  Enables or disables the specified AES interrupt.
  * @param  AES_IT: Specifies the AES interrupt source to enable/disable.
  *         This parameter can be any of the @ref AES_IT_TypeDef enumeration.
  * @param  NewState : The new state of the AES peripheral.
  *         This parameter can be any of the @ref FunctionalState enumeration.
  * @retval None
  */
void AES_ITConfig(AES_IT_TypeDef AES_IT, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_FUNCTIONAL_STATE(NewState));
  assert_param(IS_AES_IT(AES_IT));

  if (NewState != DISABLE)
  {
    AES->CR |= (uint8_t) AES_IT;    /**< AES_IT Enable */
  }
  else
  {
    AES->CR &= (uint8_t)(~AES_IT);  /**< AES_IT IDisable */
  }
}
/**
  * @brief  Write data in DINR register to be processed by AES peripheral.
  * @param  Data: The data to be processed.
  * @retval None
  */
void AES_WriteSubData(uint8_t Data)
{
  /* Write Data */
  AES->DINR = Data;
}

/**
  * @brief  Write key in DINR register.
  * @param  Key: The key to be used for encryption/decryption.
  * @retval None
  */
void AES_WriteSubKey(uint8_t Key)
{
  /* Write key */
  AES->DINR = Key;
}

/**
  * @brief  Returns the data in DOUTR register processed by AES peripheral.
  * @retval The processed data.
  */
uint8_t AES_ReadSubData(void)
{
  return AES->DOUTR;
}

/**
  * @brief  Returns the DOUTR register content.
  * @retval The derivation key.
  */
uint8_t AES_ReadSubKey(void)
{
  return AES->DOUTR;
}
/**
  * @brief  Configures the AES DMA interface.
  * @param  AES_DMATransfer: Specifies the AES DMA transfer.
  *         This parameter can be any of the @ref AES_DMATransfer_TypeDef
  *         enumeration.
  * @param  NewState Indicates the new state of the AES DMA interface.
  *         This parameter can be any of the @ref FunctionalState enumeration.
  * @retval None
  */
void AES_DMAConfig(AES_DMATransfer_TypeDef AES_DMATransfer, FunctionalState NewState)
{
  /* Check the parameter */
  assert_param(IS_AES_DMATRANSFER(AES_DMATransfer));

  if (NewState != DISABLE)
  {
    /* Enable the DMA transfer */
    AES->CR |= (uint8_t) AES_DMATransfer;
  }
  else
  {
    /* Disable the DMA transfer */
    AES->CR &= (uint8_t)(~AES_DMATransfer);
  }
}

/**
  * @brief  Checks whether the specified AES flag is set or not.
  * @param  AES_FLAG specifies the flag to check.
  *         This parameter can be any of the @ref AES_FLAG_TypeDef enumeration.
  * @retval FlagStatus (SET or RESET)
  */
FlagStatus AES_GetFlagStatus(AES_FLAG_TypeDef AES_FLAG)
{
  FlagStatus status = RESET;

  /* Check parameters */
  assert_param(IS_AES_FLAG(AES_FLAG));

  if (AES_FLAG == AES_FLAG_CCF)
  {
    if ((AES->SR & (uint8_t)AES_FLAG_CCF) != (uint8_t)0x00)
    {
      /* Computation Complete Flag CCF is set */
      status = (FlagStatus) SET;
    }
    else
    {
      /* Computation Complete Flag CCF is reset */
      status = (FlagStatus) RESET;
    }
  }
  else if (AES_FLAG == AES_FLAG_RDERR)
  {
    if ((AES->SR & (uint8_t)AES_FLAG_RDERR) != (uint8_t)0x00)
    {
      /* Read Error Flag RDERR is set */
      status = (FlagStatus) SET;
    }
    else
    {
      /* Read Error Flag RDERR is reset */
      status = (FlagStatus) RESET;
    }
  }
  else
  {
    if ((AES->SR & (uint8_t)AES_FLAG_WRERR) != (uint8_t)0x00)
    {
      /* Write Error Flag WRERR is set */
      status = (FlagStatus) SET;
    }
    else
    {
      /* Write Error Flag WRERR is reset */
      status = (FlagStatus) RESET;
    }
  }
  /* Return the AES_FLAG status */
  return ((FlagStatus) status);
}

/**
  * @brief  Clears the AES flags.
  * @param  AES_FLAG: specifies the flag to clear.
  *         This parameter can be any of the @ref AES_FLAG_TypeDef enumeration.
  * @retval None
  */
void AES_ClearFlag(AES_FLAG_TypeDef AES_FLAG)
{
  /* Check the parameters */
  assert_param(IS_AES_FLAG(AES_FLAG));

  /* Check if AES_FLAG is AES_FLAG_CCF */
  if (AES_FLAG == AES_FLAG_CCF)
  {
    /* Clear CCF flag by setting CCFC bit */
    AES->CR |= (uint8_t) AES_CR_CCFC;
  }
  else /* AES_FLAG is AES_FLAG_RDERR or AES_FLAG_WRERR */
  {
    /* Clear RDERR and WRERR flags by setting ERRC bit */
    AES->CR |= (uint8_t) AES_CR_ERRC;
  }
}

/**
  * @brief  Checks whether the specified AES interrupt has occurred or not.
  * @param  AES_IT: Specifies the AES interrupt pending bit to check.
  *         This parameter can be any of the @ref AES_IT_TypeDef enumeration.
  * @retval ITStatus The new state of AES_IT (SET or RESET).
  */
ITStatus AES_GetITStatus(AES_IT_TypeDef AES_IT)
{
  ITStatus itstatus = RESET;
  BitStatus cciebitstatus, ccfbitstatus = RESET;

  /* Check parameters */
  assert_param(IS_AES_IT(AES_IT));

  cciebitstatus = (BitStatus) (AES->CR & AES_CR_CCIE);
  ccfbitstatus =  (BitStatus) (AES->SR & AES_SR_CCF);

  /* Check if AES_IT is AES_IT_CCIE */
  if (AES_IT == AES_IT_CCIE)
  {
    /* Check the status of the specified AES interrupt */
    if (((cciebitstatus) != RESET) && ((ccfbitstatus) != RESET))
    {
      /* Interrupt occurred */
      itstatus = (ITStatus) SET;
    }
    else
    {
      /* Interrupt not occurred */
      itstatus = (ITStatus) RESET;
    }
  }
  else /* AES_IT is AES_IT_ERRIE */
  {
    /* Check the status of the specified AES interrupt */
    if ((AES->CR & AES_CR_ERRIE) != RESET)
    {
      /* Check if WRERR or RDERR flags are set */
      if ((AES->SR & (uint8_t)(AES_SR_WRERR | AES_SR_RDERR)) != RESET)
      {
        /* Interrupt occurred */
        itstatus = (ITStatus) SET;
      }
      else
      {
        /* Interrupt not occurred */
        itstatus = (ITStatus) RESET;
      }
    }
    else
    {
      /* Interrupt not occurred */
      itstatus = (ITStatus) RESET;
    }
  }

  /* Return the AES_IT status */
  return ((ITStatus)itstatus);
}

/**
  * @brief  Clears the AES's interrupt pending bits.
  * @param  AES_IT: specifies the interrupt pending bit to clear.
  *         This parameter can be any of the @ref AES_IT_TypeDef enumeration.
  * @retval None
  */
void AES_ClearITPendingBit(AES_IT_TypeDef AES_IT)
{
  /* Check the parameters */
  assert_param(IS_AES_IT(AES_IT));

  /* Check if AES_IT is AES_IT_CCIE */
  if (AES_IT == AES_IT_CCIE)
  {
    /* Clear CCF flag by setting CCFC bit */
    AES->CR |= (uint8_t) AES_CR_CCFC;
  }
  else /* AES_IT is AES_IT_ERRIE */
  {
    /* Clear RDERR and WRERR flags by setting ERRC bit */
    AES->CR |= (uint8_t) AES_CR_ERRC;
  }
}


/**
  * @}
  */

/**
  * @}
  */

/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
