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