1 /*
2  * Copyright 2017-2019 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_acomp.h"
9 
10 /*******************************************************************************
11  * Definitions
12  ******************************************************************************/
13 
14 /* Component ID definition, used by tools. */
15 #ifndef FSL_COMPONENT_ID
16 #define FSL_COMPONENT_ID "platform.drivers.lpc_acomp"
17 #endif
18 
19 /*******************************************************************************
20  * Prototypes
21  ******************************************************************************/
22 /*!
23  * @brief Get the ACOMP instance from the peripheral base address.
24  *
25  * @param base ACOMP peripheral base address.
26  * @return ACOMP instance.
27  */
28 static uint32_t ACOMP_GetInstance(ACOMP_Type *base);
29 
30 /*******************************************************************************
31  * Variables
32  ******************************************************************************/
33 /* Array of ACOMP peripheral base address. */
34 static ACOMP_Type *const s_acompBases[] = ACOMP_BASE_PTRS;
35 
36 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
37 /* Clock name of ACOMP. */
38 static const clock_ip_name_t s_acompClock[] = ACMP_CLOCKS;
39 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
40 
41 #if !(defined(FSL_FEATURE_ACMP_HAS_NO_RESET) && FSL_FEATURE_ACMP_HAS_NO_RESET)
42 /* Reset the ACMP module */
43 static const reset_ip_name_t s_acompResets[] = ACMP_RSTS_N;
44 #endif
45 
46 /*******************************************************************************
47  * Codes
48  ******************************************************************************/
ACOMP_GetInstance(ACOMP_Type * base)49 static uint32_t ACOMP_GetInstance(ACOMP_Type *base)
50 {
51     uint32_t instance;
52 
53     /* Find the instance index from base address mappings. */
54     for (instance = 0; instance < ARRAY_SIZE(s_acompBases); instance++)
55     {
56         if (s_acompBases[instance] == base)
57         {
58             break;
59         }
60     }
61 
62     assert(instance < ARRAY_SIZE(s_acompBases));
63 
64     return instance;
65 }
66 
67 /*!
68  * brief Initialize the ACOMP module.
69  *
70  * param base ACOMP peripheral base address.
71  * param config Pointer to "acomp_config_t" structure.
72  */
ACOMP_Init(ACOMP_Type * base,const acomp_config_t * config)73 void ACOMP_Init(ACOMP_Type *base, const acomp_config_t *config)
74 {
75     assert(NULL != config);
76     assert(NULL != base);
77 
78     uint32_t tmp32;
79 
80 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
81     /* Enable the clock. */
82     CLOCK_EnableClock(s_acompClock[ACOMP_GetInstance(base)]);
83 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
84 
85 #if !(defined(FSL_FEATURE_ACMP_HAS_NO_RESET) && FSL_FEATURE_ACMP_HAS_NO_RESET)
86     RESET_PeripheralReset(s_acompResets[ACOMP_GetInstance(base)]);
87 #endif
88 
89     /* Write CTRL register. */
90     tmp32 = base->CTRL & ~(ACOMP_CTRL_COMPSA_MASK | ACOMP_CTRL_HYS_MASK);
91     tmp32 |= ACOMP_CTRL_HYS(config->hysteresisSelection);
92     if (config->enableSyncToBusClk)
93     {
94         tmp32 |= ACOMP_CTRL_COMPSA_MASK;
95     }
96     base->CTRL = tmp32;
97 }
98 
99 /*!
100  * brief De-initialize the ACOMP module.
101  *
102  * param base ACOMP peripheral base address.
103  */
ACOMP_Deinit(ACOMP_Type * base)104 void ACOMP_Deinit(ACOMP_Type *base)
105 {
106 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
107     /* Disable the clock. */
108     CLOCK_DisableClock(s_acompClock[ACOMP_GetInstance(base)]);
109 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
110 }
111 
112 /*!
113  * brief Gets an available pre-defined settings for the ACOMP's configuration.
114  *
115  * This function initializes the converter configuration structure with available settings. The default values are:
116  * code
117  *   config->enableSyncToBusClk = false;
118  *   config->hysteresisSelection = kACOMP_hysteresisNoneSelection;
119  * endcode
120  * In default configuration, the ACOMP's output would be used directly and switch as the voltages cross.
121  *
122  * param base   ACOMP peripheral base address.
123  * param config Pointer to the configuration structure.
124  */
ACOMP_GetDefaultConfig(acomp_config_t * config)125 void ACOMP_GetDefaultConfig(acomp_config_t *config)
126 {
127     assert(NULL != config);
128 
129     /* Initializes the configure structure to zero. */
130     (void)memset(config, 0, sizeof(*config));
131 
132     config->enableSyncToBusClk  = false;
133     config->hysteresisSelection = kACOMP_HysteresisNoneSelection;
134 }
135 
136 /*!
137  * brief Enable ACOMP interrupts.
138  *
139  * param base ACOMP peripheral base address.
140  * param enable Enable/Disable interrupt feature.
141  */
ACOMP_EnableInterrupts(ACOMP_Type * base,acomp_interrupt_enable_t enable)142 void ACOMP_EnableInterrupts(ACOMP_Type *base, acomp_interrupt_enable_t enable)
143 {
144 #if defined(FSL_FEATURE_ACOMP_HAS_CTRL_INTENA) && FSL_FEATURE_ACOMP_HAS_CTRL_INTENA
145     if (enable == kACOMP_InterruptsDisable)
146     {
147         base->CTRL &= ~ACOMP_CTRL_INTENA_MASK;
148     }
149     else
150 #endif /*FSL_FEATURE_ACOMP_HAS_CTRL_INTENA*/
151     {
152         base->CTRL = (base->CTRL & ~ACOMP_CTRL_EDGESEL_MASK) | ACOMP_CTRL_EDGESEL(enable)
153 #if defined(FSL_FEATURE_ACOMP_HAS_CTRL_INTENA) && FSL_FEATURE_ACOMP_HAS_CTRL_INTENA
154                      | ACOMP_CTRL_INTENA_MASK
155 #endif /*FSL_FEATURE_ACOMP_HAS_CTRL_INTENA*/
156             ;
157     }
158 }
159 
160 /*!
161  * brief Set the voltage ladder configuration.
162  *
163  * param base ACOMP peripheral base address.
164  * param config The structure for voltage ladder. If the config is NULL, voltage ladder would be diasbled,
165  *               otherwise the voltage ladder would be configured and enabled.
166  */
ACOMP_SetLadderConfig(ACOMP_Type * base,const acomp_ladder_config_t * config)167 void ACOMP_SetLadderConfig(ACOMP_Type *base, const acomp_ladder_config_t *config)
168 {
169     if (NULL == config)
170     {
171         base->LAD = 0U;
172     }
173     else
174     {
175         base->LAD =
176             ACOMP_LAD_LADEN_MASK | ACOMP_LAD_LADSEL(config->ladderValue) | ACOMP_LAD_LADREF(config->referenceVoltage);
177     }
178 }
179