1 /**
2  * @file xmc_acmp.h
3  * @date 2015-09-02
4  *
5  * @cond
6  *********************************************************************************************************************
7  * XMClib v2.1.24 - XMC Peripheral Driver Library
8  *
9  * Copyright (c) 2015-2019, Infineon Technologies AG
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without modification,are permitted provided that the
13  * following conditions are met:
14  *
15  * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
16  * disclaimer.
17  *
18  * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
19  * disclaimer in the documentation and/or other materials provided with the distribution.
20  *
21  * Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote
22  * products derived from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
25  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE  FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29  * WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * To improve the quality of the software, users are encouraged to share modifications, enhancements or bug fixes with
33  * Infineon Technologies AG dave@infineon.com).
34  *********************************************************************************************************************
35  *
36  * Change History
37  * --------------
38  *
39  * 2014-12-10:
40  *     - Initial version
41  * 2015-02-20:
42  *     - Removed unused declarations<br>
43  * 2015-05-08:
44  *     - Fixed sequence problem of low power mode in XMC_ACMP_Init() API<br>
45  *     - Fixed wrong register setting in XMC_ACMP_SetInput() API<br>
46  *     - Removed return type variable and by default comparator enable from XMC_ACMP_Init() API. <br>
47  *       Additional call to XMC_ACMP_EnableComparator() API needed to start Comparator after Init.<br>
48  * 2015-06-04:
49  *     - Removed return type variable and by default comparator enable from XMC_ACMP_Init() API. <br>
50  *     - Divided XMC_ACMP_SetInput into two 3 APIs to reduce the code size and complexity as stated below<br>
51  *       (a)XMC_ACMP_EnableReferenceDivider <br>
52  *       (b)XMC_ACMP_DisableReferenceDivider <br>
53  *       (c)XMC_ACMP_SetInput <br>
54  *     - Optimized enable and disable API's and moved to header file as static inline APIs.
55  *     - XMC_ACMP_t typedef changed to structure which overrides the standard header file structure.
56  * 2015-06-20:
57  *     - Removed version macros and declaration of GetDriverVersion API
58  * 2015-06-26:
59  *     - API help documentation modified.
60  * 2015-09-02:
61  *     - API help documentation modified for XMC1400 device support.
62  * @endcond
63  *
64  */
65 
66 #ifndef XMC_ACMP_H
67 #define XMC_ACMP_H
68 
69 
70 /**
71  * @addtogroup XMClib XMC Peripheral Library
72  * @{
73  */
74 
75 /**
76  * @addtogroup ACMP
77  * @brief Analog Comparator(ACMP) low level driver for XMC1 family of microcontrollers. <br>
78  *
79  * The ACMP module consists of minimum of 3 analog comparators. Each analog comparator has two inputs, INP and INN.
80  * Input INP is compared with input INN in the pad voltage domain.
81  * It generates a digital comparator output signal. The digital comparator output signal is shifted down from VDDP
82  * power supply voltage level to VDDC core voltage level. The ACMP module provides the following functionalities.\n
83  * -# Monitor external voltage level
84  * -# Operates in low power mode
85  * -# Provides Inverted ouput option\n
86 
87  * \par The ACMP low level driver funtionalities
88  * <OL>
89  * <LI>Initializes an instance of analog comparator module with the @ref XMC_ACMP_CONFIG_t configuration structure
90  * using the API XMC_ACMP_Init().</LI>
91  * <LI>Programs the source of input(INP) specified by @ref XMC_ACMP_INP_SOURCE_t parameter using the API
92  * XMC_ACMP_SetInput(). </LI>
93  * <LI>Sets the low power mode of operation using XMC_ACMP_SetLowPowerMode() API.</LI>
94  * </OL>
95  * @{
96  */
97 
98 /*********************************************************************************************************************
99  * HEADER FILES
100  ********************************************************************************************************************/
101 #include <xmc_common.h>
102 
103 /*********************************************************************************************************************
104  * MACROS
105  ********************************************************************************************************************/
106 /* If ACMP is available*/
107 #if defined (COMPARATOR)
108 
109 #define XMC_ACMP0 (XMC_ACMP_t*)COMPARATOR /**< Comparator module base address defined*/
110 
111 #if UC_SERIES == XMC14
112 #define XMC_ACMP_MAX_INSTANCES     (4U) /* Maximum number of Analog Comparators available*/
113 #else
114 #define XMC_ACMP_MAX_INSTANCES     (3U) /* Maximum number of Analog Comparators available*/
115 #endif
116 
117 /* Checks if the pointer being passed is valid*/
118 #define XMC_ACMP_CHECK_MODULE_PTR(PTR)  (((PTR)== (XMC_ACMP_t*)COMPARATOR))
119 
120 /* Checks if the instance being addressed is valid*/
121 #define XMC_ACMP_CHECK_INSTANCE(INST)   (((INST)< XMC_ACMP_MAX_INSTANCES))
122 
123 /*********************************************************************************************************************
124  * ENUMS
125  ********************************************************************************************************************/
126 
127 /**
128  * Defines the return value of an API.
129  */
130 typedef enum XMC_ACMP_STATUS
131 {
132   XMC_ACMP_STATUS_SUCCESS = 0U, /**< API completes the execution successfully */
133   XMC_ACMP_STATUS_ERROR       , /**< API cannot fulfill the request */
134 } XMC_ACMP_STATUS_t;
135 
136 /**
137  * Defines the hysteresis voltage levels to reduce noise sensitivity.
138  */
139 typedef enum XMC_ACMP_HYSTERESIS
140 {
141   XMC_ACMP_HYSTERESIS_OFF = 0U, /**< No hysteresis */
142   XMC_ACMP_HYSTERESIS_10     ,  /**< Hysteresis = 10mv */
143   XMC_ACMP_HYSTERESIS_15     ,  /**< Hysteresis = 15mv */
144   XMC_ACMP_HYSTERESIS_20        /**< Hysteresis = 20mv */
145 } XMC_ACMP_HYSTERESIS_t;
146 
147 /**
148  *  Defines the comparator output status options.
149  */
150 typedef enum XMC_ACMP_COMP_OUT
151 {
152   XMC_ACMP_COMP_OUT_NO_INVERSION = 0U, /**< ACMP output is HIGH when, Input Positive(INP) greater than Input
153                                             Negative(INN). Vplus > Vminus */
154   XMC_ACMP_COMP_OUT_INVERSION          /**< ACMP output is HIGH when, Input Negative(INN) greater than Input
155                                             Positive(INP). Vminus > Vplus*/
156 } XMC_ACMP_COMP_OUT_t;
157 
158 /**
159  *  Defines the analog comparator input connection method.
160  */
161 typedef enum XMC_ACMP_INP_SOURCE
162 {
163   XMC_ACMP_INP_SOURCE_STANDARD_PORT  = 0U,                                          /**< Input is connected to port */
164   XMC_ACMP_INP_SOURCE_ACMP1_INP_PORT = (uint16_t)(COMPARATOR_ANACMP0_ACMP0_SEL_Msk) /**< Input is connected to port
165                                                                                      and ACMP1 INP */
166 } XMC_ACMP_INP_SOURCE_t;
167 
168 /*********************************************************************************************************************
169  * DATA STRUCTURES
170  ********************************************************************************************************************/
171 
172 
173 /*Anonymous structure/union guard start*/
174 #if defined(__CC_ARM)
175   #pragma push
176   #pragma anon_unions
177 #elif defined(__TASKING__)
178   #pragma warning 586
179 #endif
180 
181 /**
182  * ACMP module
183  */
184 typedef struct {
185   __IO uint32_t  ORCCTRL;
186   __I  uint32_t  RESERVED[726];
187   __IO uint32_t  ANACMP[XMC_ACMP_MAX_INSTANCES];
188 } XMC_ACMP_t;
189 
190 /**
191  *  Structure for initializing the ACMP module. It configures the ANACMP register of the respective input.
192  */
193 typedef struct XMC_ACMP_CONFIG
194 {
195   union
196   {
197     struct
198     {
199       uint32_t                  : 1;
200       uint32_t filter_disable   : 1; /**< Comparator filter option for removing glitches. By default this option
201                                           is selected in ANACMP register. Setting this option disables the filter */
202       uint32_t                  : 1;
203       uint32_t output_invert    : 1; /**< Option to invert the comparator output. Use XMC_@ref XMC_ACMP_COMP_OUT_t type*/
204       uint32_t hysteresis       : 2; /**< Hysteresis voltage to reduce noise sensitivity. Select the voltage levels
205                                           from the values defined in @ref XMC_ACMP_HYSTERESIS_t. */
206       uint32_t                  : 26;
207     };
208     uint32_t anacmp;
209   };
210 } XMC_ACMP_CONFIG_t;
211 
212 /*Anonymous structure/union guard end*/
213 #if defined(__CC_ARM)
214   #pragma pop
215 #elif defined(__TASKING__)
216   #pragma warning restore
217 #endif
218 
219 #ifdef __cplusplus
220    extern "C" {
221 #endif
222 
223 /*********************************************************************************************************************
224  * API Prototypes
225  ********************************************************************************************************************/
226 
227 /**
228  * @param peripheral Constant pointer to analog comparator module, of @ref XMC_ACMP_t type. Use @ref XMC_ACMP0 macro.
229  * @param instance ACMP instance number. <BR>
230  *                 Range:<BR> 0 - ACMP0<BR>
231  *                            1 - ACMP1<BR>
232  *                            2 - ACMP2<BR>
233  *                            3 - ACMP3 - Only applicable for XMC1400 devices <BR>
234  *
235  * @param config Pointer to configuration data. Refer data structure @ref XMC_ACMP_CONFIG_t for settings.
236  * @return
237  *    None<BR>
238  *
239  * \par<b>Description:</b><br>
240  *  Initializes an instance of analog comparator module.<BR>\n
241  *  Configures the ANACMP resister with hysteresis, comparator filter and inverted comparator output.
242  *
243  * \par<b>Related APIs:</b><br>
244  *  None.
245  */
246 void XMC_ACMP_Init(XMC_ACMP_t *const peripheral, uint32_t instance, const XMC_ACMP_CONFIG_t *const config);
247 
248 /**
249  * @param peripheral Constant pointer to analog comparator module, of @ref XMC_ACMP_t type. Use @ref XMC_ACMP0 macro.
250  * @param instance ACMP instance number. <BR>
251  *                 Range:<BR> 0 - ACMP0<BR>
252  *                            1 - ACMP1<BR>
253  *                            2 - ACMP2<BR>
254  *                            3 - ACMP3 - Only applicable for XMC1400 devices <BR>
255  * @return
256  *    None<BR>
257  *
258  * \par<b>Description:</b><br>
259  * Enables an instance of ACMP module.<BR>\n
260  * Starts the comparator by setting CMP_EN bit of respective ANACMP \a instance register. The \a instance number
261  * determines which analog comparator to be switched on. Call this API after the successful completion of the comparator
262  * initilization and input selection.
263  *
264  * \par<b>Related APIs:</b><br>
265  * XMC_ACMP_DisableComparator().<BR>
266  */
XMC_ACMP_EnableComparator(XMC_ACMP_t * const peripheral,uint32_t instance)267 __STATIC_INLINE void XMC_ACMP_EnableComparator(XMC_ACMP_t *const peripheral, uint32_t instance)
268 {
269   XMC_ASSERT("XMC_ACMP_EnableComparator:Wrong module pointer", XMC_ACMP_CHECK_MODULE_PTR(peripheral))
270   XMC_ASSERT("XMC_ACMP_EnableComparator:Wrong instance number", XMC_ACMP_CHECK_INSTANCE(instance) )
271 
272   peripheral->ANACMP[instance] |= (uint16_t)COMPARATOR_ANACMP0_CMP_EN_Msk;
273 
274 }
275 
276 
277 /**
278  * @param peripheral Constant pointer to analog comparator module, of @ref XMC_ACMP_t type. Use @ref XMC_ACMP0 macro.
279  * @param instance ACMP instance number. <BR>
280  *                 Range:<BR> 0 - ACMP0<BR>
281  *                            1 - ACMP1<BR>
282  *                            2 - ACMP2<BR>
283  *                            3 - ACMP3 - Only applicable for XMC1400 devices <BR>
284  * @return
285  *    None<BR>
286  * \par<b>Description:</b><br>
287  * Disables an instance of ACMP module.<BR>\n
288  * Stops the comparator by resetting CMP_EN bit of respective ANACMP \a instance register. The \a instance number
289  * determines which analog comparator to be switched off.
290  *
291  * \par<b>Related APIs:</b><br>
292  * XMC_ACMP_EnableComparator().
293  */
XMC_ACMP_DisableComparator(XMC_ACMP_t * const peripheral,uint32_t instance)294 __STATIC_INLINE void XMC_ACMP_DisableComparator(XMC_ACMP_t *const peripheral, uint32_t instance)
295 {
296   XMC_ASSERT("XMC_ACMP_DisableComparator:Wrong module pointer", XMC_ACMP_CHECK_MODULE_PTR(peripheral))
297   XMC_ASSERT("XMC_ACMP_DisableComparator:Wrong instance number", XMC_ACMP_CHECK_INSTANCE(instance) )
298 
299   peripheral->ANACMP[instance] &= (uint16_t)(~((uint32_t)COMPARATOR_ANACMP0_CMP_EN_Msk));
300 }
301 
302 /**
303  * @param None
304  * @return
305  *    None<BR>
306  *
307  * \par<b>Description:</b><br>
308  * Enables the reference divider for analog comparator instance 1.<BR>\n
309  * ACMP1 input INP is driven by an internal reference voltage by setting DIV_EN bit of ANACMP1 register.
310  * Other comparator instances can also share this reference divider option by calling the XMC_ACMP_SetInput() API.
311  *
312  * \par<b>Related APIs:</b><br>
313  * XMC_ACMP_SetInput().
314  */
XMC_ACMP_EnableReferenceDivider(void)315 __STATIC_INLINE void XMC_ACMP_EnableReferenceDivider(void)
316 {
317   /* Enable the divider switch and connect the divided reference to ACMP1.INP */
318   COMPARATOR->ANACMP1 |= (uint16_t)(COMPARATOR_ANACMP1_REF_DIV_EN_Msk);
319 }
320 
321 /**
322  * @param None
323  * @return
324  *    None<BR>
325  *
326  * \par<b>Description:</b><br>
327  * Disables the reference divider for analog comparator instance 1.<BR>\n
328  * ACMP1 input INP is disconnected from the reference divider. This is achieved by reseting DIV_EN bit of ANACMP1
329  * register.
330  *
331  * \par<b>Related APIs:</b><br>
332  * None.
333  */
XMC_ACMP_DisableReferenceDivider(void)334 __STATIC_INLINE void XMC_ACMP_DisableReferenceDivider(void)
335 {
336   /* Disable the divider switch and use ACMP1.INP as standard port*/
337   COMPARATOR->ANACMP1 &= (uint16_t)(~(COMPARATOR_ANACMP1_REF_DIV_EN_Msk));
338 }
339 
340 /**
341  * @param peripheral Constant pointer to analog comparator module, of @ref XMC_ACMP_t type. Use @ref XMC_ACMP0 macro.
342  * @param instance ACMP instance number. <BR>
343  *                 Range:<BR> 0 - ACMP0<BR>
344  *                            2 - ACMP2<BR>
345  *                            3 - ACMP3 - Only applicable for XMC1400 devices <BR>
346  * @param source ACMP input source selection options.<BR>
347  *                 Range:<BR> XMC_ACMP_INP_SOURCE_STANDARD_PORT  - Input is connected to port<BR>
348  *                            XMC_ACMP_INP_SOURCE_ACMP1_INP_PORT - Input is connected to port and ACMP1 INP <BR>
349  * @return
350  *    None<BR>
351  *
352  * \par<b>Description:</b><br>
353  * Sets the analog comparartor input selection for ACMP0, ACMP2 instances.<BR>\n
354  * Apart from ACMP1 instance, each ACMP instances can be connected to its own port and ACMP1 INP.
355  * Calling @ref XMC_ACMP_EnableReferenceDivider() API, after this API can share the reference divider to one of the
356  * comparartor input as explained in the following options.<br>
357  * The hardware options to set input are listed below.<br>
358  * <OL>
359  * <LI>The comparator inputs aren't connected to other ACMP1 comparator inputs.</LI>
360  * <LI>Can program the comparator-0 to connect ACMP0.INP to ACMP1.INP in XMC1200 AA or XMC1300 AA</LI>
361  * <LI>Can program the comparator-0 to connect ACMP0.INN to ACMP1.INP in XMC1200 AB or XMC1300 AB or XMC1400 AA</LI>
362  * <LI>Can program the comparator-2 to connect ACMP2.INP to ACMP1.INP</LI>
363  * </OL><br>
364  * Directly accessed registers are ANACMP0, ANACMP2 according to the availability of instance in the devices.
365  *
366  * \par<b>Related APIs:</b><br>
367  * @ref XMC_ACMP_EnableReferenceDivider.<BR>
368  * @ref XMC_ACMP_DisableReferenceDivider.
369  */
370 void XMC_ACMP_SetInput(XMC_ACMP_t *const peripheral, uint32_t instance, const XMC_ACMP_INP_SOURCE_t source);
371 
372 
373 /**
374  * @param None
375  * @return
376  *    None<BR>
377  *
378  * \par<b>Description:</b><br>
379  * Set the comparartors to operate in low power mode, by setting the LPWR bit of ANACMP0 register.<BR>\n
380  * The low power mode is controlled by ACMP0 instance. Low power mode is applicable for all instances of the
381  * comparator. In low power mode, blanking time will be introduced to ensure the stability of comparartor output. This
382  * will slow down the comparator operation.
383  *
384  * \par<b>Related APIs:</b><br>
385  * XMC_ACMP_ClearLowPowerMode().
386  */
XMC_ACMP_SetLowPowerMode(void)387 __STATIC_INLINE void XMC_ACMP_SetLowPowerMode(void)
388 {
389   COMPARATOR->ANACMP0 |= (uint16_t)COMPARATOR_ANACMP0_CMP_LPWR_Msk;
390 }
391 
392 /**
393  * @param None
394  * @return
395  *    None<BR>
396  *
397  * \par<b>Description:</b><br>
398  * Exits the low power mode by reseting LPWR bit of ANACMP0 register.<BR>\n
399  * The low power mode is controlled by ACMP0 module.  Low power mode is applicable for all instances of the
400  * comparator. To re-enable the low power mode, call the related API @ref XMC_ACMP_SetLowPowerMode().
401  *
402  * \par<b>Related APIs:</b><br>
403  * XMC_ACMP_SetLowPowerMode().
404  */
XMC_ACMP_ClearLowPowerMode(void)405 __STATIC_INLINE void XMC_ACMP_ClearLowPowerMode(void)
406 {
407   COMPARATOR->ANACMP0 &= (uint16_t)(~(uint16_t)COMPARATOR_ANACMP0_CMP_LPWR_Msk);
408 }
409 
410 /**
411  * @}
412  */
413 
414 /**
415  * @}
416  */
417 
418 #ifdef __cplusplus
419 }
420 #endif
421 
422 #endif /* If ACMP is available*/
423 
424 #endif /* XMC_ACMP_H */
425