1 /***************************************************************************/ /**
2 * \file cyhal_comp.c
3 *
4 * \brief
5 * Provides a high level interface for interacting with the Infineon analog
6 * comparator. This interface abstracts out the chip specific details. If any chip
7 * specific functionality is necessary, or performance is critical the low level
8 * functions can be used directly.
9 *
10 ********************************************************************************
11 * \copyright
12 * Copyright 2018-2022 Cypress Semiconductor Corporation (an Infineon company) or
13 * an affiliate of Cypress Semiconductor Corporation
14 *
15 * SPDX-License-Identifier: Apache-2.0
16 *
17 * Licensed under the Apache License, Version 2.0 (the "License");
18 * you may not use this file except in compliance with the License.
19 * You may obtain a copy of the License at
20 *
21 *     http://www.apache.org/licenses/LICENSE-2.0
22 *
23 * Unless required by applicable law or agreed to in writing, software
24 * distributed under the License is distributed on an "AS IS" BASIS,
25 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26 * See the License for the specific language governing permissions and
27 * limitations under the License.
28 *******************************************************************************/
29 #include "cyhal_comp.h"
30 #include "cyhal_comp_ctb.h"
31 #include "cyhal_comp_lp.h"
32 #include "cyhal_gpio.h"
33 #include "cyhal_system.h"
34 
35 #include <string.h> // For memset
36 
37 /**
38 * \addtogroup group_hal_impl_comp COMP (Analog Comparator)
39 * \ingroup group_hal_impl
40 * \{
41 * On CAT1 & CAT2, the comparator driver can use either of two underlying hardware blocks:
42 * - Opamp (configured as analog comparator)
43 * - LPComp (Low Power Comparator)
44 *
45 * Generally, a set of pins can only connect to either an Opamp or an LPComp but not both. In the event
46 * that both connections are possible, the LPComp will be preferred.
47 *
48 * \section group_hal_impl_comp_power Power Level Mapping
49 * The following table shows how the HAL-defined power levels map to the hardware-specific power levels.
50 * For the LPComp, some levels are named differently between CAT1 & CAT2. In this case, the differences
51 * are in brackets, with the first item being for CAT1 and the second for CAT2.
52 * | HAL Power Level                | Opamp Power Level   | LPComp Power Level           |
53 * | ------------------------------ | ------------------- | ---------------------------- |
54 * | @ref CYHAL_POWER_LEVEL_HIGH    | CY_CTB_POWER_HIGH   | CY_LPCOMP_MODE_[NORMAL/FAST] |
55 * | @ref CYHAL_POWER_LEVEL_MEDIUM  | CY_CTB_POWER_MEDIUM | CY_LPCOMP_MODE_[LP/SLOW]     |
56 * | @ref CYHAL_POWER_LEVEL_LOW     | CY_CTB_POWER_LOW    | CY_LPCOMP_MODE_ULP           |
57 * | @ref CYHAL_POWER_LEVEL_DEFAULT | CY_CTB_POWER_MEDIUM | CY_LPCOMP_MODE_[LP/SLOW]     |
58 *
59 * \} group_hal_impl_comp
60 */
61 
62 /* This file is the top-level wrapper. Comp can be implemented on top of either LPComp or the CTB Opamps */
63 #if (CYHAL_DRIVER_AVAILABLE_COMP)
64 
65 #if defined(__cplusplus)
66 extern "C"
67 {
68 #endif
69 
cyhal_comp_init(cyhal_comp_t * obj,cyhal_gpio_t vin_p,cyhal_gpio_t vin_m,cyhal_gpio_t output,cyhal_comp_config_t * cfg)70 cy_rslt_t cyhal_comp_init(cyhal_comp_t *obj, cyhal_gpio_t vin_p, cyhal_gpio_t vin_m, cyhal_gpio_t output, cyhal_comp_config_t *cfg)
71 {
72     cy_rslt_t result;
73 #if (_CYHAL_DRIVER_AVAILABLE_COMP_LP)
74     result = _cyhal_comp_lp_init(obj, vin_p, vin_m, output, cfg);
75 #endif
76 #if (_CYHAL_DRIVER_AVAILABLE_COMP_CTB)
77     #if (_CYHAL_DRIVER_AVAILABLE_COMP_LP)
78     if (CY_RSLT_SUCCESS != result)
79     #endif
80     {
81         result = _cyhal_comp_ctb_init(obj, vin_p, vin_m, output, cfg);
82     }
83 #endif
84     return result;
85 }
86 
cyhal_comp_init_cfg(cyhal_comp_t * obj,const cyhal_comp_configurator_t * cfg)87 cy_rslt_t cyhal_comp_init_cfg(cyhal_comp_t *obj, const cyhal_comp_configurator_t *cfg)
88 {
89     cy_rslt_t result = CYHAL_COMP_RSLT_ERR_BAD_ARGUMENT;
90     memset(obj, 0, sizeof(cyhal_comp_t));
91     obj->owned_by_configurator = true;
92     obj->resource = *cfg->resource;
93     obj->pin_vin_p = NC;
94     obj->pin_vin_m = NC;
95     obj->pin_out  = NC;
96 
97 #if (_CYHAL_DRIVER_AVAILABLE_COMP_LP)
98     if (CYHAL_RSC_LPCOMP == cfg->resource->type)
99     {
100         result = _cyhal_comp_lp_init_cfg(obj, cfg);
101     }
102 #endif
103 
104 #if (_CYHAL_DRIVER_AVAILABLE_COMP_CTB)
105     if (CYHAL_RSC_OPAMP == cfg->resource->type)
106     {
107         result = _cyhal_comp_ctb_init_cfg(obj, cfg);
108     }
109 #endif
110 
111     return result;
112 }
113 
cyhal_comp_free(cyhal_comp_t * obj)114 void cyhal_comp_free(cyhal_comp_t *obj)
115 {
116 #if (_CYHAL_DRIVER_AVAILABLE_COMP_CTB)
117     #if (_CYHAL_DRIVER_AVAILABLE_COMP_LP)
118     if(obj->resource.type == CYHAL_RSC_OPAMP)
119     #endif
120     {
121         _cyhal_comp_ctb_free(obj);
122     }
123 #endif
124     {
125 #if (_CYHAL_DRIVER_AVAILABLE_COMP_LP)
126     #if (_CYHAL_DRIVER_AVAILABLE_COMP_CTB)
127     if(obj->resource.type == CYHAL_RSC_LPCOMP)
128     #endif
129     {
130         _cyhal_comp_lp_free(obj);
131     }
132 #endif
133     }
134 }
135 
cyhal_comp_set_power(cyhal_comp_t * obj,cyhal_power_level_t power)136 cy_rslt_t cyhal_comp_set_power(cyhal_comp_t *obj, cyhal_power_level_t power)
137 {
138 #if (_CYHAL_DRIVER_AVAILABLE_COMP_CTB)
139     #if (_CYHAL_DRIVER_AVAILABLE_COMP_LP)
140     if(obj->resource.type == CYHAL_RSC_OPAMP)
141     #endif
142     {
143         return _cyhal_comp_ctb_set_power(obj, power);
144     }
145 #endif
146 #if (_CYHAL_DRIVER_AVAILABLE_COMP_LP)
147     CY_ASSERT(obj->resource.type == CYHAL_RSC_LPCOMP);
148     return _cyhal_comp_lp_set_power(obj, power);
149 #endif
150 }
151 
cyhal_comp_configure(cyhal_comp_t * obj,cyhal_comp_config_t * cfg)152 cy_rslt_t cyhal_comp_configure(cyhal_comp_t *obj, cyhal_comp_config_t *cfg)
153 {
154 #if (_CYHAL_DRIVER_AVAILABLE_COMP_CTB)
155     #if (_CYHAL_DRIVER_AVAILABLE_COMP_LP)
156     if(obj->resource.type == CYHAL_RSC_OPAMP)
157     #endif
158     {
159         return _cyhal_comp_ctb_configure(obj, cfg);
160     }
161 #endif
162 #if (_CYHAL_DRIVER_AVAILABLE_COMP_LP)
163     CY_ASSERT(obj->resource.type == CYHAL_RSC_LPCOMP);
164     return _cyhal_comp_lp_configure(obj, cfg);
165 #endif
166 }
167 
cyhal_comp_read(cyhal_comp_t * obj)168 bool cyhal_comp_read(cyhal_comp_t *obj)
169 {
170 #if (_CYHAL_DRIVER_AVAILABLE_COMP_CTB)
171     #if (_CYHAL_DRIVER_AVAILABLE_COMP_LP)
172     if(obj->resource.type == CYHAL_RSC_OPAMP)
173     #endif
174     {
175         return _cyhal_comp_ctb_read(obj);
176     }
177 #endif
178 #if (_CYHAL_DRIVER_AVAILABLE_COMP_LP)
179     CY_ASSERT(obj->resource.type == CYHAL_RSC_LPCOMP);
180     return _cyhal_comp_lp_read(obj);
181 #endif
182 }
183 
cyhal_comp_register_callback(cyhal_comp_t * obj,cyhal_comp_event_callback_t callback,void * callback_arg)184 void cyhal_comp_register_callback(cyhal_comp_t *obj, cyhal_comp_event_callback_t callback, void *callback_arg)
185 {
186     CY_UNUSED_PARAMETER(obj);
187     CY_ASSERT(NULL != obj);
188 
189     uint32_t savedIntrStatus = cyhal_system_critical_section_enter();
190     obj->callback_data.callback = (cy_israddress) callback;
191     obj->callback_data.callback_arg = callback_arg;
192     cyhal_system_critical_section_exit(savedIntrStatus);
193 }
194 
cyhal_comp_enable_event(cyhal_comp_t * obj,cyhal_comp_event_t event,uint8_t intr_priority,bool enable)195 void cyhal_comp_enable_event(cyhal_comp_t *obj, cyhal_comp_event_t event, uint8_t intr_priority, bool enable)
196 {
197 #if (_CYHAL_DRIVER_AVAILABLE_COMP_CTB)
198     #if (_CYHAL_DRIVER_AVAILABLE_COMP_LP)
199     if(obj->resource.type == CYHAL_RSC_OPAMP)
200     #endif
201     {
202         _cyhal_comp_ctb_enable_event(obj, event, intr_priority, enable);
203         return;
204     }
205 #endif
206 #if (_CYHAL_DRIVER_AVAILABLE_COMP_LP)
207     CY_ASSERT(obj->resource.type == CYHAL_RSC_LPCOMP);
208     _cyhal_comp_lp_enable_event(obj, event, intr_priority, enable);
209 #endif
210 }
211 
212 #if defined(__cplusplus)
213 }
214 #endif
215 
216 #endif /* CYHAL_DRIVER_AVAILABLE_COMP */
217