/** ****************************************************************************** * @file ald_dac.c * @brief DAC module driver. * * @version V1.0 * @date 28 Jun 2019 * @author AE Team. * @note * Change Logs: * Date Author Notes * 28 Jun 2019 AE Team The first version * * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ********************************************************************************** */ #include "ald_conf.h" /** @addtogroup ES32FXXX_ALD * @{ */ /** @defgroup DAC DAC * @brief DAC module driver * @{ */ #ifdef ALD_DAC /** @defgroup DAC_Public_Functions DAC Public Functions * @{ */ /** * @brief Reset the dac mode. * @param hperh: Pointer to a dac_handle_t structure that contains * the configuration information for the specified DAC module. * @retval Status, see @ref ald_status_t. */ ald_status_t ald_dac_reset(dac_handle_t *hperh) { assert_param(IS_DAC_TYPE(hperh->perh)); hperh->perh->CON = 0; hperh->perh->CH0CTRL = 0; hperh->perh->CH1CTRL = 0; hperh->perh->IES = 0; hperh->perh->IEC = 0xFF; hperh->perh->IFC = 0xFF; hperh->perh->CAL = 0; return OK; } /** * @brief Initializes the DAC peripheral. * @param hperh: Pointer to a dac_handle_t structure that contains * the configuration information for the specified DAC module. * @retval Status, see @ref ald_status_t. */ ald_status_t ald_dac_init(dac_handle_t *hperh) { uint32_t tmp; assert_param(IS_DAC_TYPE(hperh->perh)); assert_param(IS_DAC_CONVERT_TYPE(hperh->init.conv_mode)); assert_param(IS_DAC_OUTPUT_TYPE(hperh->init.out_mode)); assert_param(IS_DAC_NEG_REFRESH_TYPE(hperh->init.n_ref)); assert_param(IS_DAC_POS_REFRESH_TYPE(hperh->init.p_ref)); assert_param(IS_DAC_REFRESH_TYPE(hperh->init.refresh)); assert_param(IS_DAC_PRESCALE_TYPE(hperh->init.div)); assert_param(IS_FUNC_STATE(hperh->init.ch0_reset)); assert_param(IS_FUNC_STATE(hperh->init.o_ctrl_pis)); assert_param(IS_FUNC_STATE(hperh->init.sine)); assert_param(IS_FUNC_STATE(hperh->init.diff)); __LOCK(hperh); ald_dac_reset(hperh); DAC_CH0_DISABLE(); DAC_CH1_DISABLE(); MODIFY_REG(ADC0->CCR, ADC_CCR_VREFEN_MSK, 1 << ADC_CCR_VREFEN_POS); if (hperh->init.p_ref == DAC_POS_REF_VREEFP_BUF || hperh->init.p_ref == DAC_POS_REF_2V) SET_BIT(ADC0->CCR, (ADC_CCR_IREFEN_MSK | ADC_CCR_VRBUFEN_MSK | ADC_CCR_VCMBUFEN_MSK)); MODIFY_REG(ADC0->CCR, ADC_CCR_VRNSEL_MSK, hperh->init.n_ref << ADC_CCR_VRNSEL_POS); MODIFY_REG(ADC0->CCR, ADC_CCR_VRPSEL_MSK, hperh->init.p_ref << ADC_CCR_VRPSEL_POSS); tmp = ((hperh->init.refresh << DAC_CON_RCYCLSEL_POSS) | (hperh->init.div << DAC_CON_PRES_POSS) | (hperh->init.ch0_reset << DAC_CON_CH0PRESRST_POS) | ( hperh->init.o_ctrl_pis << DAC_CON_OUTENPIS_POS) | (hperh->init.out_mode << DAC_CON_OUTMD_POSS) | (hperh->init.conv_mode << DAC_CON_CONVMD_POSS) | (hperh->init.sine << DAC_CON_SINEMD_POS) | (hperh->init.diff << DAC_CON_DIFEN_POS)); hperh->perh->CON = tmp; /* Automatic calibration */ SET_BIT(hperh->perh->CAL, DAC_CAL_SELF_CALEN_MSK); for (tmp = 0; tmp < 1000; ++tmp); CLEAR_BIT(hperh->perh->CAL, DAC_CAL_SELF_CALEN_MSK); __UNLOCK(hperh); return OK; } /** * @brief Configure dac channel. * @param hperh: Pointer to a dac_handle_t structure that contains * the configuration information for the specified DAC module. * @param config: Pointer to a dac_channel_config_t structure that contains * the configutation information for dac channel. * @param ch: Specifies which dac channel to be config. * @retval Status, see @ref ald_status_t. */ ald_status_t ald_dac_channel_config(dac_handle_t *hperh, dac_channel_config_t *config, dac_channel_t ch) { uint32_t tmp; if ((hperh == NULL) || (config == NULL)) return ERROR; assert_param(IS_DAC_TYPE(hperh->perh)); assert_param(IS_FUNC_STATE(config->enable)); assert_param(IS_DAC_TRIGGER_TYPE(config->trigger)); assert_param(IS_FUNC_STATE(config->refresh_en)); assert_param(IS_DAC_PISSEL_CH_TYPE(config->pis_ch)); __LOCK(hperh); tmp = ((config->pis_ch << DAC_CH0CTRL_PISSEL_POSS) | (config->trigger << DAC_CH0CTRL_PISEN_POS) | (config->refresh_en << DAC_CH0CTRL_RCYCLEN_POS) | (config->enable << DAC_CH0CTRL_EN_POS)); switch (ch) { case DAC_CHANNEL_0: hperh->perh->CH0CTRL = tmp; break; case DAC_CHANNEL_1: hperh->perh->CH1CTRL = tmp; break; default: break; } __UNLOCK(hperh); return OK; } /** * @brief Set dac channel output value. * @param hperh: Pointer to a dac_handle_t structure that contains * the configuration information for the specified DAC module. * @param ch: Specifies which dac channel to be set. * @param value: The value be converted,and the valid value is low 12 bit. * @retval None */ void ald_dac_output_set(dac_handle_t *hperh, dac_channel_t ch, uint32_t value) { assert_param(IS_DAC_TYPE(hperh->perh)); assert_param(IS_DAC_CHANNEL_TYPE(ch)); switch (ch) { case DAC_CHANNEL_0: hperh->perh->CH0DATA = value; break; case DAC_CHANNEL_1: hperh->perh->CH1DATA = value; break; case DAC_CHANNEL_COMB: hperh->perh->COMBDATA = value; break; default: break; } return; } /** * @brief Checks whether the specified DAC flag is set or not. * @param hperh: Pointer to a dac_handle_t structure that contains * the configuration information for the specified dac. * @param status: Specifies the flag to check. * @retval The new state. */ flag_status_t ald_dac_get_status(dac_handle_t *hperh, dac_status_t status) { assert_param(IS_DAC_TYPE(hperh->perh)); assert_param(IS_DAC_STATUS_TYPE(status)); return hperh->perh->STAT & status ? SET : RESET; } /** * @brief Enable or disable the specified interrupt * @param hperh: Pointer to a dac_handle_t structure that contains * the configuration information for the specified DAC. * @param it: Specifies the interrupt type to be enabled or disabled * @arg @ref DAC_IT_CH0 Channel 0 conversion complete interrupt * @arg @ref DAC_IT_CH1 Channel 1 conversion complete interrupt * @arg @ref DAC_IT_CH0_UF Channel 0 data underflow interrupt * @arg @ref DAC_IT_CH1_UF Channel 1 data underflow interrupt * @param state: New state of the specified interrupt. * This parameter can be: ENABLE or DISABLE * @retval Status, see @ref ald_status_t. */ void ald_dac_interrupt_config(dac_handle_t *hperh, dac_it_t it, type_func_t state) { assert_param(IS_DAC_TYPE(hperh->perh)); assert_param(IS_DAC_INTERRUPT_TYPE(it)); assert_param(IS_FUNC_STATE(state)); if (state) hperh->perh->IES |= it; else hperh->perh->IEC = it; return; } /** * @brief Get the status of DAC interrupt source. * @param hperh: Pointer to a dac_handle_t structure that contains * the configuration information for the specified DAC. * @param it: Specifies the DAC interrupt source. * @retval Status: * - 0: RESET * - 1: SET */ it_status_t ald_dac_get_it_status(dac_handle_t *hperh, dac_it_t it) { assert_param(IS_DAC_TYPE(hperh->perh)); assert_param(IS_DAC_INTERRUPT_TYPE(it)); return hperh->perh->IEV & it ? SET : RESET; } /** * @brief Checks whether the specified interrupt has occurred or not. * @param hperh: Pointer to a dac_handle_t structure that contains * the configuration information for the specified DAC. * @param flag: Specifies the interrupt type to check. * @retval The new state. */ flag_status_t ald_dac_get_flag_status(dac_handle_t *hperh, dac_flag_t flag) { assert_param(IS_DAC_TYPE(hperh->perh)); assert_param(IS_DAC_FLAG_TYPE(flag)); return hperh->perh->RIF & flag ? SET : RESET; } /** * @brief Get the status of interrupt flag and interupt source. * @param hperh: Pointer to a dac_handle_t structure that contains * the configuration information for the specified DAC. * @param flag: Specifies the DAC interrupt flag. * @retval Status: * - 0: RESET * - 1: SET */ flag_status_t ald_dac_get_mask_flag_status(dac_handle_t *hperh, dac_flag_t flag) { assert_param(IS_DAC_TYPE(hperh->perh)); assert_param(IS_DAC_FLAG_TYPE(flag)); return hperh->perh->IFM & flag ? SET : RESET; } /** * @brief Clear interrupt state flag * @param hperh: Pointer to a dac_handle_t structure that contains * the configuration information for the specified DAC. * @param flag: Specifies the interrupt type to clear * @retval None */ void ald_dac_clear_flag_status(dac_handle_t *hperh, dac_flag_t flag) { assert_param(IS_DAC_TYPE(hperh->perh)); assert_param(IS_DAC_FLAG_TYPE(flag)); hperh->perh->IFC = flag; return; } /** * @brief This function handles DAC event interrupt request. * @param hperh: Pointer to a dac_handle_t structure that contains * the configuration information for the specified DAC. * @retval None */ void ald_dac_irq_handler(dac_handle_t *hperh) { if (ald_dac_get_mask_flag_status(hperh, DAC_FLAG_CH0)) { ald_dac_clear_flag_status(hperh, DAC_FLAG_CH0); if (hperh->cbk) hperh->cbk(hperh, DAC_EVENT_CH0_CPLT); } if (ald_dac_get_mask_flag_status(hperh, DAC_FLAG_CH1)) { ald_dac_clear_flag_status(hperh, DAC_FLAG_CH1); if (hperh->cbk) hperh->cbk(hperh, DAC_EVENT_CH1_CPLT); } if (ald_dac_get_mask_flag_status(hperh, DAC_FLAG_CH0_UF)) { ald_dac_clear_flag_status(hperh, DAC_FLAG_CH0_UF); if (hperh->cbk) hperh->cbk(hperh, DAC_EVENT_CH0_UF); } if (ald_dac_get_mask_flag_status(hperh, DAC_FLAG_CH1_UF)) { ald_dac_clear_flag_status(hperh, DAC_FLAG_CH1_UF); if (hperh->cbk) hperh->cbk(hperh, DAC_EVENT_CH1_UF); } return; } /** *@} */ #endif /* ALD_DAC */ /** *@} */ /** *@} */