/**
  *********************************************************************************
  *
  * @file    hal_calc.c
  * @brief   CALC module driver.
  *
  * @version V1.0
  * @date    04 Dec 2017
  * @author  AE Team
  * @note
  *
  * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
  *
  *********************************************************************************
  */

#include "hal_calc.h"


/** @addtogroup ES32FXXX_HAL
  * @{
  */

/** @defgroup CALC CALC
  * @brief CALC module driver
  * @{
  */
#ifdef HAL_CALC

/** @defgroup CALC_Public_Functions CALC Public Functions
  * @brief    Accelerating calculate functions
  *
  * @verbatim
  ==============================================================================
              ##### Accelerating calculate functions #####
  ==============================================================================
    [..]  This section provides functions allowing to:
      (+) Square root operation.
      (+) Division.
      (+) Get DZ flag.

    @endverbatim
  * @{
  */

/**
  * @brief  Square root operation.
  * @param  data: The data;
  * @retval The value of square root.
  */
uint32_t calc_sqrt(uint32_t data)
{
	CALC->RDCND.RADICAND = data;
	while (CALC->SQRTSR.BUSY);

	return CALC->SQRTRES.RESULT;
}

/**
  * @brief  Calculating division.
  * @param  dividend: The value of the dividend.
  * @param  divisor: The value of the divisor.
  * @param  remainder: The value of the remainder.
  * @retval The result of division.
  */
uint32_t calc_div(uint32_t dividend, uint32_t divisor, uint32_t *remainder)
{
	CALC->DIVCSR.SIGN = 0;
	CALC->DIVCSR.TRM  = 1;
	CALC->DIVDR.Word  = dividend;
	CALC->DIVSR.Word  = divisor;

	while(CALC->DIVCSR.BUSY);

	*remainder = CALC->DIVRR.Word;
	return CALC->DIVQR.Word;
}

/**
  * @brief  Calculating division.
  * @param  dividend: The value of the dividend.
  * @param  divisor: The value of the divisor.
  * @param  remainder: The value of the remainder.
  * @retval The result of division.
  */
int32_t calc_div_sign(int32_t dividend, int32_t divisor, int32_t *remainder)
{
	CALC->DIVCSR.SIGN = 1;
	CALC->DIVCSR.TRM  = 1;
	CALC->DIVDR.Word  = dividend;
	CALC->DIVSR.Word  = divisor;

	while(CALC->DIVCSR.BUSY);

	*remainder = CALC->DIVRR.Word;
	return CALC->DIVQR.Word;
}

/**
  * @brief  Get the flag of divisor is zero.
  * @retval The status, SET/RESET.
  */
flag_status_t calc_get_dz_status(void)
{
	return CALC->DIVCSR.DZ == 0 ? RESET : SET;
}

/**
  * @}
  */
#endif /* HAL_CALC */
/**
  * @}
  */

/**
  * @}
  */
