1 /**
2   *********************************************************************************
3   *
4   * @file    ald_acmp.c
5   * @brief   ACMP module driver.
6   *
7   * @version V1.0
8   * @date    13 Dec 2017
9   * @author  AE Team
10   * @note
11   *
12   * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
13   *
14   * SPDX-License-Identifier: Apache-2.0
15   *
16   * Licensed under the Apache License, Version 2.0 (the License); you may
17   * not use this file except in compliance with the License.
18   * You may obtain a copy of the License at
19   *
20   * www.apache.org/licenses/LICENSE-2.0
21   *
22   * Unless required by applicable law or agreed to in writing, software
23   * distributed under the License is distributed on an AS IS BASIS, WITHOUT
24   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25   * See the License for the specific language governing permissions and
26   * limitations under the License.
27   *
28   *********************************************************************************
29   */
30 
31 #include "ald_acmp.h"
32 
33 /** @addtogroup ES32FXXX_ALD
34   * @{
35   */
36 
37 /** @defgroup ACMP ACMP
38   * @brief ACMP module driver
39   * @{
40   */
41 #ifdef ALD_ACMP
42 
43 /** @defgroup ACMP_Public_Functions ACMP Public Functions
44   * @{
45   */
46 
47 /** @defgroup ACMP_Public_Functions_Group1 Initialization functions
48   * @brief Initialization and Configuration functions
49   * @{
50   */
51 
52 /**
53   * @brief  Initializes the ACMP mode according to the specified parameters in
54   *         the acmp_init_t and create the associated handle.
55   * @param  hperh: Pointer to a acmp_handle_t structure that contains
56   *         the configuration information for the specified ACMP module.
57   * @retval Status, see @ref ald_status_t.
58   */
ald_acmp_init(acmp_handle_t * hperh)59 ald_status_t ald_acmp_init(acmp_handle_t *hperh)
60 {
61 	uint32_t tmp = 0;
62 
63 	if (hperh == NULL)
64 		return ERROR;
65 
66 	if (hperh->init.vdd_level > 63)
67 		return ERROR;
68 
69 	assert_param(IS_ACMP_TYPE(hperh->perh));
70 	assert_param(IS_ACMP_MODE_TYPE(hperh->init.mode));
71 	assert_param(IS_ACMP_WARM_UP_TIME_TYPE(hperh->init.warm_time));
72 	assert_param(IS_ACMP_HYSTSEL_TYPE(hperh->init.hystsel));
73 	assert_param(IS_ACMP_WARM_FUNC_TYPE(hperh->init.warm_func));
74 	assert_param(IS_ACMP_POS_INPUT_TYPE(hperh->init.pos_port));
75 	assert_param(IS_ACMP_NEG_INPUT_TYPE(hperh->init.neg_port));
76 	assert_param(IS_ACMP_INACTVAL_TYPE(hperh->init.inactval));
77 	assert_param(IS_ACMP_EDGE_TYPE(hperh->init.edge));
78 
79 	__LOCK(hperh);
80 
81 	tmp = hperh->perh->CON;
82 
83 	tmp |= ((hperh->init.mode << ACMP_CON_MODSEL_POSS) | (hperh->init.warm_time << ACMP_CON_WARMUPT_POSS) |
84 		(hperh->init.inactval << ACMP_CON_INACTV_POS) | (hperh->init.hystsel << ACMP_CON_HYSTSEL_POSS));
85 
86 	hperh->perh->CON = tmp;
87 
88 	tmp = hperh->perh->INPUTSEL;
89 
90 	tmp |= ((hperh->init.pos_port << ACMP_INPUTSEL_PSEL_POSS) | (hperh->init.neg_port << ACMP_INPUTSEL_NSEL_POSS) |
91 		(hperh->init.vdd_level << ACMP_INPUTSEL_VDDLVL_POSS));
92 
93 	hperh->perh->INPUTSEL = tmp;
94 
95 	if (hperh->init.warm_func == ACMP_WARM_DISABLE)
96 		CLEAR_BIT(hperh->perh->IES, ACMP_IES_WARMUP_MSK);
97 	else
98 		SET_BIT(hperh->perh->IES, ACMP_IES_WARMUP_MSK);
99 
100 	switch (hperh->init.edge) {
101 	case ACMP_EDGE_NONE:
102 		CLEAR_BIT(hperh->perh->CON, ACMP_CON_FALLEN_MSK);
103 		CLEAR_BIT(hperh->perh->CON, ACMP_CON_RISEEN_MSK);
104 		break;
105 
106 	case ACMP_EDGE_FALL:
107 		SET_BIT(hperh->perh->CON, ACMP_CON_FALLEN_MSK);
108 		CLEAR_BIT(hperh->perh->CON, ACMP_CON_RISEEN_MSK);
109 		break;
110 
111 	case ACMP_EDGE_RISE:
112 		CLEAR_BIT(hperh->perh->CON, ACMP_CON_FALLEN_MSK);
113 		SET_BIT(hperh->perh->CON, ACMP_CON_RISEEN_MSK);
114 		break;
115 
116 	case ACMP_EDGE_ALL:
117 		SET_BIT(hperh->perh->CON, ACMP_CON_FALLEN_MSK);
118 		SET_BIT(hperh->perh->CON, ACMP_CON_RISEEN_MSK);
119 		break;
120 
121 	default:
122 		break;
123 	}
124 
125 	SET_BIT(hperh->perh->CON, ACMP_CON_EN_MSK);
126 
127 	tmp = 0;
128 	while (READ_BIT(hperh->perh->STAT, ACMP_STAT_ACT_MSK) == 0) {
129 		if (tmp++ >= 600000) {
130 			__UNLOCK(hperh);
131 			return ERROR;
132 		}
133 	}
134 
135 	__UNLOCK(hperh);
136 	return OK;
137 }
138 /**
139   * @}
140   */
141 
142 /** @defgroup ACMP_Public_Functions_Group2 Interrupt operation functions
143   * @brief ACMP Interrupt operation functions
144   * @{
145   */
146 
147 /**
148   * @brief  Enables or disables the specified ACMP interrupts.
149   * @param  hperh: Pointer to a acmp_handle_t structure that contains
150   *         the configuration information for the specified ACMP module.
151   * @param  it: Specifies the ACMP interrupt sources to be enabled or disabled.
152   *         This parameter can be one of the @ref acmp_it_t.
153   * @param  state: New status
154   *           - ENABLE
155   *           - DISABLE
156   * @retval Status, see @ref ald_status_t.
157   */
ald_acmp_interrupt_config(acmp_handle_t * hperh,acmp_it_t it,type_func_t state)158 ald_status_t ald_acmp_interrupt_config(acmp_handle_t *hperh, acmp_it_t it, type_func_t state)
159 {
160 	assert_param(IS_ACMP_TYPE(hperh->perh));
161 	assert_param(IS_ACMP_IT_TYPE(it));
162 	assert_param(IS_FUNC_STATE(state));
163 
164 	__LOCK(hperh);
165 
166 	if (state)
167 		hperh->perh->IES |= it;
168 	else
169 		hperh->perh->IEC |= it;
170 
171 	__UNLOCK(hperh);
172 
173 	return OK;
174 }
175 
176 /**
177   * @brief  Checks whether the specified ACMP interrupt has set or not.
178   * @param  hperh: Pointer to a acmp_handle_t structure that contains
179   *         the configuration information for the specified ACMP module.
180   * @param  it: Specifies the ACMP interrupt sources to be enabled or disabled.
181   *         This parameter can be one of the @ref acmp_it_t.
182   * @retval it_status_t
183   *           - SET
184   *           - RESET
185   */
ald_acmp_get_it_status(acmp_handle_t * hperh,acmp_it_t it)186 it_status_t ald_acmp_get_it_status(acmp_handle_t *hperh, acmp_it_t it)
187 {
188 	assert_param(IS_ACMP_TYPE(hperh->perh));
189 	assert_param(IS_ACMP_IT_TYPE(it));
190 
191 	if (hperh->perh->IEV & it)
192 		return SET;
193 	else
194 		return RESET;
195 }
196 
197 /**
198   * @brief  Checks whether the specified ACMP interrupt has occurred or not.
199   * @param  hperh: Pointer to a acmp_handle_t structure that contains
200   *         the configuration information for the specified ACMP module.
201   * @param  flag: Specifies the ACMP interrupt source to check.
202   *         This parameter can be one of the @ref acmp_it_t.
203   * @retval it_status_t
204   *           - SET
205   *           - RESET
206   */
ald_acmp_get_flag_status(acmp_handle_t * hperh,acmp_flag_t flag)207 it_status_t ald_acmp_get_flag_status(acmp_handle_t *hperh, acmp_flag_t flag)
208 {
209 	assert_param(IS_ACMP_TYPE(hperh->perh));
210 	assert_param(IS_ACMP_FLAG_TYPE(flag));
211 
212 	if (hperh->perh->RIF & flag) {
213 		__UNLOCK(hperh);
214 		return SET;
215 	}
216 
217 	return RESET;
218 }
219 
220 /** @brief  Clear the specified ACMP it flags.
221   * @param  hperh: Pointer to a acmp_handle_t structure that contains
222   *         the configuration information for the specified ACMP module.
223   * @param  flag: specifies the it flag.
224   *         This parameter can be one of the @ref acmp_it_t.
225   * @retval Status, see @ref ald_status_t.
226   */
ald_acmp_clear_flag_status(acmp_handle_t * hperh,acmp_flag_t flag)227 ald_status_t ald_acmp_clear_flag_status(acmp_handle_t *hperh, acmp_flag_t flag)
228 {
229 	assert_param(IS_ACMP_TYPE(hperh->perh));
230 	assert_param(IS_ACMP_FLAG_TYPE(flag));
231 
232 	__LOCK(hperh);
233 	hperh->perh->IFC |= flag;
234 	__UNLOCK(hperh);
235 
236 	return OK;
237 }
238 
239 /** @brief  Set the specified acmp it flags.
240   * @param  hperh: Pointer to a acmp_handle_t structure that contains
241   *         the configuration information for the specified acmp module.
242   * @param  it: specifies the  it flag.
243   *         This parameter can be one of the @ref acmp_it_t.
244   * @retval Status, see @ref ald_status_t.
245   */
acmp_set_it_mask(acmp_handle_t * hperh,acmp_it_t it)246 ald_status_t acmp_set_it_mask(acmp_handle_t *hperh, acmp_it_t it)
247 {
248 	assert_param(IS_ACMP_TYPE(hperh->perh));
249 	assert_param(IS_ACMP_IT_TYPE(it));
250 
251 	__LOCK(hperh);
252 	hperh->perh->IFM |= it;
253 	__UNLOCK(hperh);
254 
255 	return OK;
256 }
257 
258 /** @brief  Check whether the specified ACMP flag is set or not.
259   * @param  hperh: Pointer to a acmp_handle_t structure that contains
260   *         the configuration information for the specified ACMP module.
261   * @param  status: specifies the status to check.
262   *         This parameter can be one of the @ref acmp_status_t.
263   * @retval flag_status_t
264   *           - SET
265   *           - RESET
266   */
ald_acmp_get_status(acmp_handle_t * hperh,acmp_status_t status)267 flag_status_t ald_acmp_get_status(acmp_handle_t *hperh, acmp_status_t status)
268 {
269 	assert_param(IS_ACMP_TYPE(hperh->perh));
270 	assert_param(IS_ACMP_STATUS_TYPE(status));
271 
272 	if (hperh->perh->STAT & status) {
273 		__UNLOCK(hperh);
274 		return SET;
275 	}
276 
277 	return RESET;
278 }
279 /**
280   * @}
281   */
282 
283 /** @defgroup ACMP_Public_Functions_Group3 Output value functions
284   * @brief ACMP Output value functions
285   * @{
286   */
287 
288 /**
289   * @brief  This function handles ACMP interrupt request.
290   * @param  hperh: Pointer to a acmp_handle_t structure that contains
291   *         the configuration information for the specified ACMP module.
292   * @retval None
293   */
ald_acmp_irq_handler(acmp_handle_t * hperh)294 void ald_acmp_irq_handler(acmp_handle_t *hperh)
295 {
296 	if ((ald_acmp_get_flag_status(hperh, ACMP_FLAG_WARMUP) == SET) && (ald_acmp_get_it_status(hperh, ACMP_IT_WARMUP) == SET)) {
297 		if (hperh->acmp_warmup_cplt_cbk)
298 			hperh->acmp_warmup_cplt_cbk(hperh);
299 		ald_acmp_clear_flag_status(hperh, ACMP_FLAG_WARMUP);
300 	}
301 
302 	if ((ald_acmp_get_flag_status(hperh, ACMP_FLAG_EDGE) == SET) && (ald_acmp_get_it_status(hperh, ACMP_IT_EDGE) == SET)) {
303 		if (hperh->acmp_edge_cplt_cbk)
304 			hperh->acmp_edge_cplt_cbk(hperh);
305 		ald_acmp_clear_flag_status(hperh, ACMP_FLAG_EDGE);
306 	}
307 
308 	return;
309 }
310 
311 /**
312   * @brief  This function config acmp output.
313   * @param  hperh: Pointer to a acmp_handle_t structure that contains
314   *         the configuration information for the specified ACMP module.
315   * @param  config: Pointer to a acmp_output_config_t structure that contains
316   *         the configutation information for acmp output.
317   * @retval Status, see @ref ald_status_t.
318   */
ald_acmp_out_config(acmp_handle_t * hperh,acmp_output_config_t * config)319 ald_status_t ald_acmp_out_config(acmp_handle_t *hperh, acmp_output_config_t *config)
320 {
321 	if (hperh == NULL)
322 		return ERROR;
323 
324 	if (config == NULL)
325 		return ERROR;
326 
327 	assert_param(IS_ACMP_TYPE(hperh->perh));
328 	assert_param(IS_ACMP_INVERT_TYPE(config->gpio_inv));
329 	assert_param(IS_ACMP_OUT_FUNC_TYPE(config->out_func));
330 
331 	__LOCK(hperh);
332 	hperh->perh->CON |= (config->gpio_inv << ACMP_CON_OUTINV_POS);
333 	hperh->perh->PORT = config->out_func;
334 	__UNLOCK(hperh);
335 
336 	return OK;
337 }
338 
339 /**
340   * @brief  This function output acmp result.
341   * @param  hperh: Pointer to a acmp_handle_t structure that contains
342   *         the configuration information for the specified ACMP module.
343   * @retval output value.
344   */
ald_acmp_out_result(acmp_handle_t * hperh)345 uint8_t ald_acmp_out_result(acmp_handle_t *hperh)
346 {
347 	assert_param(IS_ACMP_TYPE(hperh->perh));
348 
349 	return (READ_BIT(hperh->perh->STAT, ACMP_STAT_OUT_MSK) >> ACMP_STAT_OUT_POS);
350 }
351 /**
352   * @}
353   */
354 
355 /**
356   * @}
357   */
358 #endif /* ALD_ACMP */
359 /**
360   * @}
361   */
362 
363 /**
364   * @}
365   */
366