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

#include "hal_temp.h"


/** @addtogroup ES32FXXX_HAL
  * @{
  */

/** @defgroup TEMP TEMP
  * @brief TEMP module driver
  * @{
  */
#ifdef HAL_TEMP


/** @defgroup TEMP_Private_Variables TEMP Private Variables
  * @{
  */
temp_cbk __temp_cbk;
/**
  * @}
  */

/** @defgroup TEMP_Public_Functions TEMP Public Functions
  * @{
  */

/** @addtogroup TEMP_Public_Functions_Group1 Initialization functions
  * @brief Initialization functions
  *
  * @verbatim
  ==============================================================================
              ##### Initialization functions #####
  ==============================================================================
    [..]  This section provides functions allowing to initialize the TEMP:
      (+) This parameters can be configured:
        (++) Update Cycle
        (++) Output Mode
        (++) Perscaler

    @endverbatim
  * @{
  */

/**
  * @brief  Initializes the TEMP according to the specified
  *         parameters in the temp_init_t.
  * @param  init: Pointer to a temp_init_t structure that contains
  *         the configuration information.
  * @retval None
  */
void temp_init(temp_init_t *init)
{
	assert_param(IS_TEMP_UPDATE_CYCLE(init->cycle));
	assert_param(IS_TEMP_OUTPUT_MODE(init->mode));

	TEMP_UNLOCK();
	TEMP->CR.TSU  = init->cycle;
	TEMP->CR.TOM  = init->mode;
	TEMP->PSR.PRS = init->psc;
	TEMP_LOCK();

	return;
}
/**
  * @}
  */

/** @addtogroup TEMP_Public_Functions_Group2 Peripheral Control functions
  * @brief Peripheral Control functions
  *
  * @verbatim
  ==============================================================================
              ##### Peripheral Control functions #####
  ==============================================================================
  [..]  This section provides functions allowing to:
    (+) temp_get_value() API can get the current temperature.
    (+) temp_get_value_by_it() API can get the current temperature by interrupt.
    (+) temp_irq_handle() API can handle the interrupt request.

    @endverbatim
  * @{
  */

/**
  * @brief  Get the current temperature
  * @param  temp: The value of current temperature.
  * @retval HAL status:
  *         @arg @ref OK    The value is valid
  *         @arg @ref ERROR The value is invalid
  */
hal_status_t temp_get_value(uint16_t *temp)
{
	TEMP_UNLOCK();
	TEMP->IFCR.TEMPC = 1;
	TEMP->CR.EN      = 1;
	TEMP_LOCK();

	while (!(TEMP->IF.TEMPF));

	TEMP_UNLOCK();
	TEMP->IFCR.TEMPC = 1;
	TEMP_LOCK();

	if (TEMP->DR.ERR)
		return ERROR;

	*temp = TEMP->DR.DATA;
	return OK;
}

/**
  * @brief  Get the current temperature by interrupt
  * @param  cbk: The callback function
  * @retval None
  */
void temp_get_value_by_it(temp_cbk cbk)
{
	__temp_cbk = cbk;

	TEMP_UNLOCK();
	TEMP->IFCR.TEMPC = 1;
	TEMP->IE.TEMPE    = 1;
	TEMP->CR.EN      = 1;
	TEMP_LOCK();

	return;
}

/**
  * @brief  This function handles TEMP interrupt request.
  * @retval None
  */
void temp_irq_handle(void)
{
	TEMP_UNLOCK();
	TEMP->IFCR.TEMPC = 1;
	TEMP_LOCK();

	if ((TEMP->DR.ERR) && (__temp_cbk != NULL)) {
		__temp_cbk(0, ERROR);
		return;
	}

	if (__temp_cbk != NULL)
		__temp_cbk(TEMP->DR.DATA, OK);

	return;
}
/**
  * @}
  */
/**
  * @}
  */
#endif /* HAL_TEMP */
/**
  * @}
  */

/**
  * @}
  */
