1 /**
2   ******************************************************************************
3   * @file    ald_dac.c
4   * @brief   DAC module driver.
5   *
6   * @version V1.0
7   * @date    28 Jun 2019
8   * @author  AE Team.
9   * @note
10   *          Change Logs:
11   *          Date            Author          Notes
12   *          28 Jun 2019     AE Team         The first version
13   *
14   * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
15   *
16   * SPDX-License-Identifier: Apache-2.0
17   *
18   * Licensed under the Apache License, Version 2.0 (the License); you may
19   * not use this file except in compliance with the License.
20   * You may obtain a copy of the License at
21   *
22   * www.apache.org/licenses/LICENSE-2.0
23   *
24   * Unless required by applicable law or agreed to in writing, software
25   * distributed under the License is distributed on an AS IS BASIS, WITHOUT
26   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
27   * See the License for the specific language governing permissions and
28   * limitations under the License.
29   **********************************************************************************
30   */
31 
32 #include "ald_conf.h"
33 
34 
35 /** @addtogroup ES32FXXX_ALD
36   * @{
37   */
38 
39 /** @defgroup DAC DAC
40   * @brief DAC module driver
41   * @{
42   */
43 #ifdef ALD_DAC
44 
45 /** @defgroup DAC_Public_Functions DAC Public Functions
46   * @{
47   */
48 /**
49   * @brief  Reset the dac mode.
50   * @param  hperh: Pointer to a dac_handle_t structure that contains
51   *         the configuration information for the specified DAC module.
52   * @retval Status, see @ref ald_status_t.
53   */
ald_dac_reset(dac_handle_t * hperh)54 ald_status_t ald_dac_reset(dac_handle_t *hperh)
55 {
56 	assert_param(IS_DAC_TYPE(hperh->perh));
57 
58 	hperh->perh->CON      = 0;
59 	hperh->perh->CH0CTRL  = 0;
60 	hperh->perh->CH1CTRL  = 0;
61 	hperh->perh->IES      = 0;
62 	hperh->perh->IEC      = 0xFF;
63 	hperh->perh->IFC      = 0xFF;
64 	hperh->perh->CAL      = 0;
65 
66 	return OK;
67 }
68 
69 /**
70   * @brief  Initializes the DAC peripheral.
71   * @param  hperh: Pointer to a dac_handle_t structure that contains
72   *         the configuration information for the specified DAC module.
73   * @retval Status, see @ref ald_status_t.
74   */
ald_dac_init(dac_handle_t * hperh)75 ald_status_t ald_dac_init(dac_handle_t *hperh)
76 {
77 	uint32_t tmp;
78 
79 	assert_param(IS_DAC_TYPE(hperh->perh));
80 	assert_param(IS_DAC_CONVERT_TYPE(hperh->init.conv_mode));
81 	assert_param(IS_DAC_OUTPUT_TYPE(hperh->init.out_mode));
82 	assert_param(IS_DAC_NEG_REFRESH_TYPE(hperh->init.n_ref));
83 	assert_param(IS_DAC_POS_REFRESH_TYPE(hperh->init.p_ref));
84 	assert_param(IS_DAC_REFRESH_TYPE(hperh->init.refresh));
85 	assert_param(IS_DAC_PRESCALE_TYPE(hperh->init.div));
86 	assert_param(IS_FUNC_STATE(hperh->init.ch0_reset));
87 	assert_param(IS_FUNC_STATE(hperh->init.o_ctrl_pis));
88 	assert_param(IS_FUNC_STATE(hperh->init.sine));
89 	assert_param(IS_FUNC_STATE(hperh->init.diff));
90 
91 	__LOCK(hperh);
92 	ald_dac_reset(hperh);
93 	DAC_CH0_DISABLE();
94 	DAC_CH1_DISABLE();
95 
96 	MODIFY_REG(ADC0->CCR, ADC_CCR_VREFEN_MSK, 1 << ADC_CCR_VREFEN_POS);
97 
98 	if (hperh->init.p_ref == DAC_POS_REF_VREEFP_BUF || hperh->init.p_ref == DAC_POS_REF_2V)
99 		SET_BIT(ADC0->CCR, (ADC_CCR_IREFEN_MSK | ADC_CCR_VRBUFEN_MSK | ADC_CCR_VCMBUFEN_MSK));
100 
101 	MODIFY_REG(ADC0->CCR, ADC_CCR_VRNSEL_MSK, hperh->init.n_ref << ADC_CCR_VRNSEL_POS);
102 	MODIFY_REG(ADC0->CCR, ADC_CCR_VRPSEL_MSK, hperh->init.p_ref << ADC_CCR_VRPSEL_POSS);
103 
104 	tmp = ((hperh->init.refresh << DAC_CON_RCYCLSEL_POSS) | (hperh->init.div << DAC_CON_PRES_POSS) |
105 	       (hperh->init.ch0_reset << DAC_CON_CH0PRESRST_POS) | ( hperh->init.o_ctrl_pis << DAC_CON_OUTENPIS_POS) |
106 	       (hperh->init.out_mode << DAC_CON_OUTMD_POSS) | (hperh->init.conv_mode << DAC_CON_CONVMD_POSS) |
107 	       (hperh->init.sine << DAC_CON_SINEMD_POS) | (hperh->init.diff << DAC_CON_DIFEN_POS));
108 	hperh->perh->CON = tmp;
109 
110 	/* Automatic calibration */
111 	SET_BIT(hperh->perh->CAL, DAC_CAL_SELF_CALEN_MSK);
112 	for (tmp = 0; tmp < 1000; ++tmp);
113 	CLEAR_BIT(hperh->perh->CAL, DAC_CAL_SELF_CALEN_MSK);
114 
115 	__UNLOCK(hperh);
116 	return OK;
117 }
118 
119 /**
120   * @brief  Configure dac channel.
121   * @param  hperh: Pointer to a dac_handle_t structure that contains
122   *         the configuration information for the specified DAC module.
123   * @param  config: Pointer to a dac_channel_config_t structure that contains
124   *         the configutation information for dac channel.
125   * @param  ch: Specifies which dac channel to be config.
126   * @retval Status, see @ref ald_status_t.
127   */
ald_dac_channel_config(dac_handle_t * hperh,dac_channel_config_t * config,dac_channel_t ch)128 ald_status_t ald_dac_channel_config(dac_handle_t *hperh, dac_channel_config_t *config, dac_channel_t ch)
129 {
130 	uint32_t tmp;
131 
132 	if ((hperh == NULL) || (config == NULL))
133 		return ERROR;
134 
135 	assert_param(IS_DAC_TYPE(hperh->perh));
136 	assert_param(IS_FUNC_STATE(config->enable));
137 	assert_param(IS_DAC_TRIGGER_TYPE(config->trigger));
138 	assert_param(IS_FUNC_STATE(config->refresh_en));
139 	assert_param(IS_DAC_PISSEL_CH_TYPE(config->pis_ch));
140 
141 	__LOCK(hperh);
142 	tmp = ((config->pis_ch << DAC_CH0CTRL_PISSEL_POSS) | (config->trigger << DAC_CH0CTRL_PISEN_POS) |
143 	       (config->refresh_en << DAC_CH0CTRL_RCYCLEN_POS) | (config->enable << DAC_CH0CTRL_EN_POS));
144 
145 	switch (ch) {
146 	case DAC_CHANNEL_0:
147 		hperh->perh->CH0CTRL = tmp;
148 		break;
149 
150 	case DAC_CHANNEL_1:
151 		hperh->perh->CH1CTRL = tmp;
152 		break;
153 
154 	default:
155 		break;
156 	}
157 
158 	__UNLOCK(hperh);
159 	return OK;
160 }
161 
162 /**
163   * @brief  Set dac channel output value.
164   * @param  hperh: Pointer to a dac_handle_t structure that contains
165   *         the configuration information for the specified DAC module.
166   * @param  ch: Specifies which dac channel to be set.
167   * @param  value: The value be converted,and the valid value is low 12 bit.
168   * @retval None
169   */
ald_dac_output_set(dac_handle_t * hperh,dac_channel_t ch,uint32_t value)170 void ald_dac_output_set(dac_handle_t *hperh, dac_channel_t ch, uint32_t value)
171 {
172 	assert_param(IS_DAC_TYPE(hperh->perh));
173 	assert_param(IS_DAC_CHANNEL_TYPE(ch));
174 
175 	switch (ch) {
176 	case DAC_CHANNEL_0:
177 		hperh->perh->CH0DATA = value;
178 		break;
179 
180 	case DAC_CHANNEL_1:
181 		hperh->perh->CH1DATA = value;
182 		break;
183 
184 	case DAC_CHANNEL_COMB:
185 		hperh->perh->COMBDATA = value;
186 		break;
187 
188 	default:
189 		break;
190 	}
191 
192 	return;
193 }
194 
195 /**
196   * @brief  Checks whether the specified DAC flag is set or not.
197   * @param  hperh: Pointer to a dac_handle_t structure that contains
198   *               the configuration information for the specified dac.
199   * @param  status: Specifies the flag to check.
200   * @retval The new state.
201   */
ald_dac_get_status(dac_handle_t * hperh,dac_status_t status)202 flag_status_t ald_dac_get_status(dac_handle_t *hperh, dac_status_t status)
203 {
204 	assert_param(IS_DAC_TYPE(hperh->perh));
205 	assert_param(IS_DAC_STATUS_TYPE(status));
206 
207 	return hperh->perh->STAT & status ? SET : RESET;
208 }
209 
210 /**
211   * @brief Enable or disable the specified interrupt
212   * @param hperh: Pointer to a dac_handle_t structure that contains
213   *               the configuration information for the specified DAC.
214   * @param it: Specifies the interrupt type to be enabled or disabled
215   *        @arg @ref DAC_IT_CH0 Channel 0 conversion complete interrupt
216   *        @arg @ref DAC_IT_CH1 Channel 1 conversion complete interrupt
217   *        @arg @ref DAC_IT_CH0_UF Channel 0 data underflow interrupt
218   *        @arg @ref DAC_IT_CH1_UF Channel 1 data underflow interrupt
219   * @param state: New state of the specified interrupt.
220   *        This parameter can be: ENABLE or DISABLE
221   * @retval Status, see @ref ald_status_t.
222   */
ald_dac_interrupt_config(dac_handle_t * hperh,dac_it_t it,type_func_t state)223 void ald_dac_interrupt_config(dac_handle_t *hperh, dac_it_t it, type_func_t state)
224 {
225 	assert_param(IS_DAC_TYPE(hperh->perh));
226 	assert_param(IS_DAC_INTERRUPT_TYPE(it));
227 	assert_param(IS_FUNC_STATE(state));
228 
229 	if (state)
230 		hperh->perh->IES |= it;
231 	else
232 		hperh->perh->IEC = it;
233 
234 	return;
235 }
236 
237 /**
238   * @brief  Get the status of DAC interrupt source.
239   * @param  hperh: Pointer to a dac_handle_t structure that contains
240   *               the configuration information for the specified DAC.
241   * @param  it: Specifies the DAC interrupt source.
242   * @retval Status:
243   *           - 0: RESET
244   *           - 1: SET
245   */
ald_dac_get_it_status(dac_handle_t * hperh,dac_it_t it)246 it_status_t ald_dac_get_it_status(dac_handle_t *hperh, dac_it_t it)
247 {
248 	assert_param(IS_DAC_TYPE(hperh->perh));
249 	assert_param(IS_DAC_INTERRUPT_TYPE(it));
250 
251 	return hperh->perh->IEV & it ? SET : RESET;
252 }
253 
254 /**
255   * @brief Checks whether the specified interrupt has occurred or not.
256   * @param hperh: Pointer to a dac_handle_t structure that contains
257   *               the configuration information for the specified DAC.
258   * @param flag: Specifies the interrupt type to check.
259   * @retval The new state.
260   */
ald_dac_get_flag_status(dac_handle_t * hperh,dac_flag_t flag)261 flag_status_t ald_dac_get_flag_status(dac_handle_t *hperh, dac_flag_t flag)
262 {
263 	assert_param(IS_DAC_TYPE(hperh->perh));
264 	assert_param(IS_DAC_FLAG_TYPE(flag));
265 
266 	return hperh->perh->RIF & flag ? SET : RESET;
267 }
268 
269 /**
270   * @brief  Get the status of interrupt flag and interupt source.
271   * @param  hperh: Pointer to a dac_handle_t structure that contains
272   *               the configuration information for the specified DAC.
273   * @param  flag: Specifies the DAC interrupt flag.
274   * @retval Status:
275   *           - 0: RESET
276   *           - 1: SET
277   */
ald_dac_get_mask_flag_status(dac_handle_t * hperh,dac_flag_t flag)278 flag_status_t ald_dac_get_mask_flag_status(dac_handle_t *hperh, dac_flag_t flag)
279 {
280 	assert_param(IS_DAC_TYPE(hperh->perh));
281 	assert_param(IS_DAC_FLAG_TYPE(flag));
282 
283 	return hperh->perh->IFM & flag ? SET : RESET;
284 }
285 
286 /**
287   * @brief  Clear interrupt state flag
288   * @param  hperh: Pointer to a dac_handle_t structure that contains
289   *               the configuration information for the specified DAC.
290   * @param  flag: Specifies the interrupt type to clear
291   * @retval None
292   */
ald_dac_clear_flag_status(dac_handle_t * hperh,dac_flag_t flag)293 void ald_dac_clear_flag_status(dac_handle_t *hperh, dac_flag_t flag)
294 {
295 	assert_param(IS_DAC_TYPE(hperh->perh));
296 	assert_param(IS_DAC_FLAG_TYPE(flag));
297 
298 	hperh->perh->IFC = flag;
299 	return;
300 }
301 
302 /**
303   * @brief  This function handles DAC event interrupt request.
304   * @param hperh: Pointer to a dac_handle_t structure that contains
305   *               the configuration information for the specified DAC.
306   * @retval None
307   */
ald_dac_irq_handler(dac_handle_t * hperh)308 void ald_dac_irq_handler(dac_handle_t *hperh)
309 {
310 	if (ald_dac_get_mask_flag_status(hperh, DAC_FLAG_CH0)) {
311 		ald_dac_clear_flag_status(hperh, DAC_FLAG_CH0);
312 
313 		if (hperh->cbk)
314 			hperh->cbk(hperh, DAC_EVENT_CH0_CPLT);
315 	}
316 
317 	if (ald_dac_get_mask_flag_status(hperh, DAC_FLAG_CH1)) {
318 		ald_dac_clear_flag_status(hperh, DAC_FLAG_CH1);
319 
320 		if (hperh->cbk)
321 			hperh->cbk(hperh, DAC_EVENT_CH1_CPLT);
322 	}
323 
324 	if (ald_dac_get_mask_flag_status(hperh, DAC_FLAG_CH0_UF)) {
325 		ald_dac_clear_flag_status(hperh, DAC_FLAG_CH0_UF);
326 
327 		if (hperh->cbk)
328 			hperh->cbk(hperh, DAC_EVENT_CH0_UF);
329 	}
330 
331 	if (ald_dac_get_mask_flag_status(hperh, DAC_FLAG_CH1_UF)) {
332 		ald_dac_clear_flag_status(hperh, DAC_FLAG_CH1_UF);
333 
334 		if (hperh->cbk)
335 			hperh->cbk(hperh, DAC_EVENT_CH1_UF);
336 	}
337 
338 	return;
339 }
340 /**
341   *@}
342   */
343 #endif /* ALD_DAC */
344 /**
345   *@}
346   */
347 /**
348   *@}
349   */
350