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

#include "hal_opamp.h"

/** @addtogroup ES32FXXX_HAL
  * @{
  */

/** @defgroup OPAMP OPAMP
  * @brief OPAMP module driver
  * @{
  */
#ifdef HAL_OPAMP

/** @defgroup OPAMP_Public_Functions OPAMP Public Functions
  * @{
  */
/**
  * @brief  Initializes the OPAMP mode according to the specified parameters in
  *         the opamp_init_t and create the associated handle.
  * @param  hperh: Pointer to a opamp_handle_t structure that contains
  *         the configuration information for the specified OPAMP module.
  * @param  index: Specifies which opa to be initialized.
  * @retval Status, see @ref hal_status_t.
  */
hal_status_t opamp_init(opamp_handle_t *hperh, opamp_index_t index)
{
	if (hperh == NULL)
		return ERROR;

	assert_param(IS_OPAMP_TYPE(hperh->perh));
	assert_param(IS_OPAMP_INDEX_TYPE(index));
	assert_param(IS_OPAMP_POSSEL_TYPE(hperh->init.pos_input));
	assert_param(IS_OPAMP_NEGSEL_TYPE(hperh->init.neg_input));
	assert_param(IS_OPAMP_RES_IN_TYPE(hperh->init.res_input));
	assert_param(IS_OPAMP_RESSEL_TYPE(hperh->init.ressel));

	__LOCK(hperh);

	switch (index) {
	case OPAMP_INDEX_0:
		hperh->perh->OPA0MUX.POSSEL   = hperh->init.pos_input;
		hperh->perh->OPA0MUX.NEGSEL   = hperh->init.neg_input;
		hperh->perh->OPA0MUX.RESINMUX = hperh->init.res_input;
		hperh->perh->OPA0MUX.RESSEL   = hperh->init.ressel;
		hperh->perh->OPA0MUX.NPEN     = 1;
		hperh->perh->OPA0MUX.PPEN     = 1;
		hperh->perh->OPACTRL.OPA0EN   = 1;
		break;

	case OPAMP_INDEX_1:
		hperh->perh->OPA1MUX.POSSEL   = hperh->init.pos_input;
		hperh->perh->OPA1MUX.NEGSEL   = hperh->init.neg_input;
		hperh->perh->OPA1MUX.RESINMUX = hperh->init.res_input;
		hperh->perh->OPA1MUX.RESSEL   = hperh->init.ressel;
		hperh->perh->OPA1MUX.NPEN     = 1;
		hperh->perh->OPA1MUX.PPEN     = 1;
		hperh->perh->OPACTRL.OPA1EN   = 1;
		break;

	case OPAMP_INDEX_2:
		hperh->perh->OPA2MUX.POSSEL   = hperh->init.pos_input;
		hperh->perh->OPA2MUX.NEGSEL   = hperh->init.neg_input;
		hperh->perh->OPA2MUX.RESINMUX = hperh->init.res_input;
		hperh->perh->OPA2MUX.RESSEL   = hperh->init.ressel;
		hperh->perh->OPA2MUX.NPEN     = 1;
		hperh->perh->OPA2MUX.PPEN     = 1;
		hperh->perh->OPACTRL.OPA2EN   = 1;
		break;

	default:
		break;
	}

	__UNLOCK(hperh);
	return OK;
}

/**
  * @brief  This function config opamp output.
  * @param  hperh: Pointer to a opamp_handle_t structure that contains
  *         the configuration information for the specified OPAMP module.
  * @param  config: Pointer to a opamp_output_config_t structure that contains
  *         the configutation information for opamp output.
  * @param  index: Specifies which opa to be config.
  * @retval Status, see @ref hal_status_t.
  */
hal_status_t opamp_output_config(opamp_handle_t *hperh, opamp_output_config_t *config, opamp_index_t index)
{
	if ((hperh == NULL) || (config == NULL) || (config->altemate_out > 31))
		return ERROR;

	assert_param(IS_OPAMP_TYPE(hperh->perh));
	assert_param(IS_OPAMP_OUT_MODE_TYPE(config->out_mode));
	assert_param(IS_OPAMP_NEXT_OUT_TYPE(config->next_en));

	__LOCK(hperh);

	switch (index) {
	case OPAMP_INDEX_0:
		hperh->perh->OPA0MUX.NEXTOUT = config->next_en;
		hperh->perh->OPA0MUX.OUTMODE = config->out_mode;
		hperh->perh->OPA0MUX.OUTPEN  = config->altemate_out;
		break;

	case OPAMP_INDEX_1:
		hperh->perh->OPA1MUX.NEXTOUT = config->next_en;
		hperh->perh->OPA1MUX.OUTMODE = config->out_mode;
		hperh->perh->OPA1MUX.OUTPEN  = config->altemate_out;
		break;

	case OPAMP_INDEX_2:
		hperh->perh->OPA2MUX.NEXTOUT = config->next_en;
		hperh->perh->OPA2MUX.OUTMODE = config->out_mode;

		if ((config->altemate_out != OPAMP_OUTPUT_DISABLE)
		         || (config->altemate_out != OPAMP_MAIN_OUTPUT)) {
			__UNLOCK(hperh);
			return ERROR;
		}

		hperh->perh->OPA2MUX.OUTPEN = config->altemate_out;
		break;

	default:
		break;
	}

	__UNLOCK(hperh);
	return OK;
}
/**
  * @}
  */

#endif /* HAL_OPAMP */
/**
  * @}
  */

/**
  * @}
  */
