• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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