1 /*
2 * Copyright (c) 2021 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #ifndef HPM_ACMP_DRV_H
9 #define HPM_ACMP_DRV_H
10
11 #include "hpm_common.h"
12 #include "hpm_acmp_regs.h"
13
14 /**
15 * @brief ACMP driver APIs
16 * @defgroup acmp_interface ACMP driver APIs
17 * @ingroup io_interfaces
18 * @{
19 *
20 */
21
22 /***********************************************************************************************************************
23 *
24 * Definitions
25 *
26 **********************************************************************************************************************/
27
28 /**
29 * @brief ACMP hysteresis level
30 */
31 #define ACMP_HYST_LEVEL_0 (0U)
32 #define ACMP_HYST_LEVEL_1 (1U)
33 #define ACMP_HYST_LEVEL_2 (2U)
34 #define ACMP_HYST_LEVEL_3 (3U)
35
36 /**
37 * @brief ACMP input channel number
38 */
39 #define ACMP_INPUT_DAC_OUT (0U)
40 #define ACMP_INPUT_ANALOG_1 (1U)
41 #define ACMP_INPUT_ANALOG_2 (2U)
42 #define ACMP_INPUT_ANALOG_3 (3U)
43 #define ACMP_INPUT_ANALOG_4 (4U)
44 #define ACMP_INPUT_ANALOG_5 (5U)
45 #define ACMP_INPUT_ANALOG_6 (6U)
46 #define ACMP_INPUT_ANALOG_7 (7U)
47
48 /**
49 * @brief ACMP output digital filter mode
50 */
51 #define ACMP_FILTER_MODE_BYPASS (0U)
52 #define ACMP_FILTER_MODE_CHANGE_IMMEDIATELY (4U)
53 #define ACMP_FILTER_MODE_CHANGE_AFTER_FILTER (5U)
54 #define ACMP_FILTER_MODE_STABLE_LOW (6U)
55 #define ACMP_FILTER_MODE_STABLE_HIGH (7U)
56
57 /**
58 * @brief ACMP rising/falling flage mask
59 */
60 #define ACMP_EVENT_RISING_EDGE (1U)
61 #define ACMP_EVENT_FALLING_EDGE (2U)
62
63 /**
64 * @brief ACMP channel config
65 */
66
67 typedef struct acmp_channel_config {
68 uint8_t plus_input;
69 uint8_t minus_input;
70 uint8_t filter_mode;
71 uint8_t hyst_level;
72 bool enable_cmp_output;
73 bool enable_window_mode;
74 bool invert_output;
75 bool enable_clock_sync;
76 bool bypass_filter;
77 bool enable_dac;
78 bool enable_hpmode;
79 uint16_t filter_length; /* ACMP output digital filter length in ACMP clock cycle */
80 } acmp_channel_config_t;
81
82 #ifdef __cplusplus
83 extern "C" {
84 #endif
85
86 /**
87 * @brief ACMP channel config DAC output value
88 *
89 * @param [in] ptr ACMP base address
90 * @param [in] ch ACMP channel number
91 * @param [in] value DAC output value
92 */
acmp_channel_config_dac(ACMP_Type * ptr,uint8_t ch,uint32_t value)93 static inline void acmp_channel_config_dac(ACMP_Type *ptr, uint8_t ch, uint32_t value)
94 {
95 ptr->CHANNEL[ch].DACCFG = ACMP_CHANNEL_DACCFG_DACCFG_SET(value);
96 }
97
98 /**
99 * @brief ACMP channel clear status
100 *
101 * @param [in] ptr ACMP base address
102 * @param [in] ch ACMP channel number
103 * @param [in] mask :
104 * @arg ACMP_EVENT_RISING_EDGE: ACMP output rising flag
105 * @arg ACMP_EVENT_FALLING_EDGE: ACMP output fall flag
106 */
acmp_channel_clear_status(ACMP_Type * ptr,uint8_t ch,uint32_t mask)107 static inline void acmp_channel_clear_status(ACMP_Type *ptr, uint8_t ch, uint32_t mask)
108 {
109 ptr->CHANNEL[ch].SR = mask;
110 }
111
112 /**
113 * @brief ACMP channel get status
114 *
115 * @param [in] ptr ACMP base address
116 * @param [in] ch ACMP channel number
117 * @retval ACMP channel's status
118 */
acmp_channel_get_status(ACMP_Type * ptr,uint8_t ch)119 static inline uint32_t acmp_channel_get_status(ACMP_Type *ptr, uint8_t ch)
120 {
121 return ptr->CHANNEL[ch].SR;
122 }
123
124 /**
125 * @brief ACMP channel enable DMA request
126 *
127 * @param [in] ptr ACMP base address
128 * @param [in] ch ACMP channel number
129 * @param [in] mask :
130 * @arg ACMP_EVENT_RISING_EDGE: ACMP output rising flag
131 * @arg ACMP_EVENT_FALLING_EDGE: ACMP output fall flag
132 * @param [in] enable:
133 * @arg true: enable
134 * @arg false: disable
135 */
acmp_channel_dma_request_enable(ACMP_Type * ptr,uint8_t ch,uint32_t mask,bool enable)136 static inline void acmp_channel_dma_request_enable(ACMP_Type *ptr, uint8_t ch,
137 uint32_t mask, bool enable)
138 {
139 ptr->CHANNEL[ch].DMAEN = (ptr->CHANNEL[ch].DMAEN & ~mask)
140 | (enable ? mask : 0);
141 }
142
143 /**
144 * @brief ACMP channel enable IRQ
145 *
146 * @param [in] ptr ACMP base address
147 * @param [in] ch ACMP channel number
148 * @param [in] mask :
149 * @arg ACMP_EVENT_RISING_EDGE: ACMP output rising flag
150 * @arg ACMP_EVENT_FALLING_EDGE: ACMP output fall flag
151 * @param [in] enable:
152 * @arg true: enable
153 * @arg false: disable
154 */
acmp_channel_enable_irq(ACMP_Type * ptr,uint8_t ch,uint32_t mask,bool enable)155 static inline void acmp_channel_enable_irq(ACMP_Type *ptr, uint8_t ch,
156 uint32_t mask, bool enable)
157 {
158 ptr->CHANNEL[ch].IRQEN = (ptr->CHANNEL[ch].IRQEN & ~mask)
159 | (enable ? mask : 0);
160 }
161
162 /**
163 * @brief ACMP channel enable DAC
164 *
165 * @param [in] ptr ACMP base address
166 * @param [in] ch ACMP channel number
167 * @param [in] enable:
168 * @arg true: enable
169 * @arg false: disable
170 */
acmp_channel_enable_dac(ACMP_Type * ptr,uint8_t ch,bool enable)171 static inline void acmp_channel_enable_dac(ACMP_Type *ptr, uint8_t ch, bool enable)
172 {
173 ptr->CHANNEL[ch].CFG = (ptr->CHANNEL[ch].CFG & ~ACMP_CHANNEL_CFG_DACEN_MASK)
174 | ACMP_CHANNEL_CFG_DACEN_SET(enable);
175 }
176
177 /**
178 * @brief ACMP channel enable high performance mode
179 *
180 * @param [in] ptr ACMP base address
181 * @param [in] ch ACMP channel number
182 * @param [in] enable:
183 * @arg true: enable
184 * @arg false: disable
185 */
acmp_channel_enable_hpmode(ACMP_Type * ptr,uint8_t ch,bool enable)186 static inline void acmp_channel_enable_hpmode(ACMP_Type *ptr, uint8_t ch, bool enable)
187 {
188 ptr->CHANNEL[ch].CFG = (ptr->CHANNEL[ch].CFG & ~ACMP_CHANNEL_CFG_HPMODE_MASK)
189 | ACMP_CHANNEL_CFG_HPMODE_SET(enable);
190 }
191
192 /**
193 * @brief ACMP channel enable hysteresis level
194 *
195 * @param [in] ptr ACMP base address
196 * @param [in] ch ACMP channel number
197 * @param [in] level: ACMP hysteresis level
198 */
acmp_channel_set_hyst(ACMP_Type * ptr,uint8_t ch,uint8_t level)199 static inline void acmp_channel_set_hyst(ACMP_Type *ptr, uint8_t ch, uint8_t level)
200 {
201 ptr->CHANNEL[ch].CFG = (ptr->CHANNEL[ch].CFG & ~ACMP_CHANNEL_CFG_HYST_MASK)
202 | ACMP_CHANNEL_CFG_HYST_SET(level);
203 }
204
205 /**
206 * @brief ACMP channel enable comparator
207 *
208 * @param [in] ptr ACMP base address
209 * @param [in] ch ACMP channel number
210 * @param [in] enable:
211 * @arg true: enable
212 * @arg false: disable
213 */
acmp_channel_enable_cmp(ACMP_Type * ptr,uint8_t ch,bool enable)214 static inline void acmp_channel_enable_cmp(ACMP_Type *ptr, uint8_t ch, bool enable)
215 {
216 ptr->CHANNEL[ch].CFG = (ptr->CHANNEL[ch].CFG & ~ACMP_CHANNEL_CFG_CMPEN_MASK)
217 | ACMP_CHANNEL_CFG_CMPEN_SET(enable);
218 }
219
220 /**
221 * @brief ACMP channel enable comparator output
222 *
223 * @param [in] ptr ACMP base address
224 * @param [in] ch ACMP channel number
225 * @param [in] enable:
226 * @arg true: enable
227 * @arg false: disable
228 */
acmp_channel_enable_cmp_output(ACMP_Type * ptr,uint8_t ch,bool enable)229 static inline void acmp_channel_enable_cmp_output(ACMP_Type *ptr, uint8_t ch, bool enable)
230 {
231 ptr->CHANNEL[ch].CFG = (ptr->CHANNEL[ch].CFG & ~ACMP_CHANNEL_CFG_CMPOEN_MASK)
232 | ACMP_CHANNEL_CFG_CMPOEN_SET(enable);
233 }
234
235 /**
236 * @brief ACMP channel bypass comparator output filter
237 *
238 * @param [in] ptr ACMP base address
239 * @param [in] ch ACMP channel number
240 * @param [in] enable:
241 * @arg true: bypass
242 * @arg false: not bypass
243 */
acmp_channel_cmp_output_bypass_filter(ACMP_Type * ptr,uint8_t ch,bool enable)244 static inline void acmp_channel_cmp_output_bypass_filter(ACMP_Type *ptr, uint8_t ch, bool enable)
245 {
246 ptr->CHANNEL[ch].CFG = (ptr->CHANNEL[ch].CFG & ~ACMP_CHANNEL_CFG_FLTBYPS_MASK)
247 | ACMP_CHANNEL_CFG_FLTBYPS_SET(!enable);
248 }
249
250 /**
251 * @brief ACMP channel enable comparator window mode
252 *
253 * @param [in] ptr ACMP base address
254 * @param [in] ch ACMP channel number
255 * @param [in] enable:
256 * @arg true: enable
257 * @arg false: disable
258 */
acmp_channel_enable_cmp_window_mode(ACMP_Type * ptr,uint8_t ch,bool enable)259 static inline void acmp_channel_enable_cmp_window_mode(ACMP_Type *ptr, uint8_t ch, bool enable)
260 {
261 ptr->CHANNEL[ch].CFG = (ptr->CHANNEL[ch].CFG & ~ACMP_CHANNEL_CFG_WINEN_MASK)
262 | ACMP_CHANNEL_CFG_WINEN_SET(enable);
263 }
264
265 /**
266 * @brief ACMP channel invert comparator output
267 *
268 * @param [in] ptr ACMP base address
269 * @param [in] ch ACMP channel number
270 * @param [in] enable:
271 * @arg true: invert
272 * @arg false: not invert
273 */
acmp_channel_invert_output(ACMP_Type * ptr,uint8_t ch,bool enable)274 static inline void acmp_channel_invert_output(ACMP_Type *ptr, uint8_t ch, bool enable)
275 {
276 ptr->CHANNEL[ch].CFG = (ptr->CHANNEL[ch].CFG & ~ACMP_CHANNEL_CFG_OPOL_MASK)
277 | ACMP_CHANNEL_CFG_OPOL_SET(enable);
278 }
279
280 /**
281 * @brief ACMP channel set comparator output filter mode
282 *
283 * @param [in] ptr ACMP base address
284 * @param [in] ch ACMP channel number
285 * @param [in] filter: ACMP output digital filter mode definition
286 */
acmp_channel_set_filter_mode(ACMP_Type * ptr,uint8_t ch,uint8_t filter)287 static inline void acmp_channel_set_filter_mode(ACMP_Type *ptr, uint8_t ch, uint8_t filter)
288 {
289 ptr->CHANNEL[ch].CFG = (ptr->CHANNEL[ch].CFG & ~ACMP_CHANNEL_CFG_FLTMODE_MASK)
290 | ACMP_CHANNEL_CFG_FLTMODE_SET(filter);
291 }
292
293 /**
294 * @brief ACMP channel enable comparator output sync with clock
295 *
296 * @param [in] ptr ACMP base address
297 * @param [in] ch ACMP channel number
298 * @param [in] enable:
299 * @arg true: enable
300 * @arg false: disable
301 */
acmp_channel_enable_sync(ACMP_Type * ptr,uint8_t ch,bool enable)302 static inline void acmp_channel_enable_sync(ACMP_Type *ptr, uint8_t ch, bool enable)
303 {
304 ptr->CHANNEL[ch].CFG = (ptr->CHANNEL[ch].CFG & ~ACMP_CHANNEL_CFG_SYNCEN_MASK)
305 | ACMP_CHANNEL_CFG_SYNCEN_SET(enable);
306 }
307
308 /**
309 * @brief ACMP channel set comparator output filter length
310 *
311 * @param [in] ptr ACMP base address
312 * @param [in] ch ACMP channel number
313 * @param [in] filter_length: filter length in clock cycles
314 */
acmp_channel_set_filter_length(ACMP_Type * ptr,uint8_t ch,uint16_t filter_length)315 static inline void acmp_channel_set_filter_length(ACMP_Type *ptr, uint8_t ch, uint16_t filter_length)
316 {
317 ptr->CHANNEL[ch].CFG = (ptr->CHANNEL[ch].CFG & ~ACMP_CHANNEL_CFG_FLTLEN_MASK)
318 | ACMP_CHANNEL_CFG_FLTLEN_SET(filter_length);
319 }
320
321 /**
322 * @brief ADC channel config
323 *
324 * @param [in] ptr ACMP base address
325 * @param [in] ch ACMP channel number
326 * @param [in] config: acmp_channel_config_t
327 * @param [in] enable:
328 * @arg true: enable comparator
329 * @arg false: disable comparator
330 *
331 * @retval hpm_stat_t
332 */
333 hpm_stat_t acmp_channel_config(ACMP_Type *ptr, uint8_t ch, acmp_channel_config_t *config, bool enable);
334
335 /**
336 * @brief ADC channel get default config setting
337 *
338 * @param [in] ptr ACMP base address
339 * @param [out] config: acmp_channel_config_t
340 */
341 void acmp_channel_get_default_config(ACMP_Type *ptr, acmp_channel_config_t *config);
342
343 /**
344 * @}
345 *
346 */
347
348 #ifdef __cplusplus
349 }
350 #endif
351
352 #endif /* HPM_ACMP_DRV_H */
353