1 /***************************************************************************//**
2 * \file cyhal_analog_common.h
3 *
4 * \brief
5 * Provides common functionality that needs to be shared among all drivers that
6 * interact with the Programmable Analog Subsystem.
7 *
8 ********************************************************************************
9 * \copyright
10 * Copyright 2018-2022 Cypress Semiconductor Corporation (an Infineon company) or
11 * an affiliate of Cypress Semiconductor Corporation
12 *
13 * SPDX-License-Identifier: Apache-2.0
14 *
15 * Licensed under the Apache License, Version 2.0 (the "License");
16 * you may not use this file except in compliance with the License.
17 * You may obtain a copy of the License at
18 *
19 * http://www.apache.org/licenses/LICENSE-2.0
20 *
21 * Unless required by applicable law or agreed to in writing, software
22 * distributed under the License is distributed on an "AS IS" BASIS,
23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 * See the License for the specific language governing permissions and
25 * limitations under the License.
26 *******************************************************************************/
27
28 #pragma once
29
30 #include <stdint.h>
31 #include "cyhal_hw_types.h"
32 #include "cyhal_general_types.h"
33 #include "cyhal_gpio.h"
34
35 #if (_CYHAL_DRIVER_AVAILABLE_COMP_CTB)
36 #include "cy_ctb.h"
37
38 #if defined(CY_IP_MXS40PASS_CTB_INSTANCES)
39 #define _CYHAL_CTB_INSTANCES CY_IP_MXS40PASS_CTB_INSTANCES
40 #define _CYHAL_CTB_SW_OPEN CY_CTB_SWITCH_OPEN
41 #define _CYHAL_CTB_SW_CLOSE CY_CTB_SWITCH_CLOSE
42 #define _CYHAL_CTB_PUMP_ENABLE CY_CTB_PUMP_ENABLE
43 #define _CYHAL_COMP_CTB_DEFAULT_BYPASS CY_CTB_COMP_BYPASS_NO_SYNC
44 #define _CYHAL_COMP_CTB_HIST(hysteresis) ((hysteresis) ? CY_CTB_COMP_HYST_10MV : CY_CTB_COMP_HYST_DISABLE)
45 #elif defined(CY_IP_M0S8PASS4A_CTB_INSTANCES)
46 #define _CYHAL_CTB_INSTANCES CY_IP_M0S8PASS4A_CTB_INSTANCES
47 #define _CYHAL_CTB_SW_OPEN false
48 #define _CYHAL_CTB_SW_CLOSE true
49 #define _CYHAL_CTB_PUMP_ENABLE true
50 #define _CYHAL_COMP_CTB_DEFAULT_BYPASS false
51 #define _CYHAL_COMP_CTB_HIST(hysteresis) (hysteresis)
52 #else
53 #error Unhandled PASS IP Block
54 #endif
55 #endif
56
57 #if (_CYHAL_DRIVER_AVAILABLE_PASS)
58
59 #if defined(__cplusplus)
60 extern "C" {
61 #endif
62
63 /**
64 * Initialize the programmable analog. This utilizes reference counting to avoid
65 * repeatedly initializing the analog subsystem when multiple analog blocks are in use
66 * */
67 void _cyhal_analog_init(void);
68
69 /**
70 * Uninitialize the programmable analog. This utilizes reference counting to avoid
71 * disabling the analog subsystem until all blocks which require it have been freed.
72 */
73 void _cyhal_analog_free(void);
74
75 #if (_CYHAL_DRIVER_AVAILABLE_COMP_CTB)
76
77 /**
78 * Initialize the programmable analog for CTB. This utilizes reference counting to avoid
79 * repeatedly initializing the analog subsystem when multiple analog blocks are in use
80 *
81 * @param[in] base CTB(m) base address
82 * */
83 void cyhal_analog_ctb_init(CTBM_Type *base);
84
85 /**
86 * Uninitialize the programmable analog. This utilizes reference counting to avoid
87 * disabling the analog subsystem until all blocks which require it have been freed.
88 *
89 * @param[in] base CTB(m) base address
90 */
91 void cyhal_analog_ctb_free(CTBM_Type *base);
92
93 /** Base address for each CTB */
94 extern CTBM_Type *const _cyhal_ctb_base[];
95
96 /**
97 * Computes the switch mask to use for a set of opamp pins
98 *
99 * @param[in] opamp_num Opamp number (index within CTB(m))
100 * @param[in] vin_p Non-inverting input pin. Must be specified.
101 * @param[in] vin_m Inverting input pin. May be NC.
102 * @param[in] vout Opamp output pin (analog). May be NC.
103 * @return the switch mask to use
104 */
105 uint32_t _cyhal_opamp_pin_to_mask(uint8_t opamp_num, cyhal_gpio_t vin_p, cyhal_gpio_t vin_m, cyhal_gpio_t vout);
106
107 /**
108 * Performs basic initialization of an opamp and its associated set of pins that is common to
109 * both opamp and comparator mode.
110 * This reserves resources and configures switches to connect the pins. It does not configure the
111 * opamp hardware.
112 * If this returns success, the opamp and all pins will be reserved. If an error is returned, all resources
113 * that were successfully reserved will have been freed.
114 *
115 * @param[out] rsc The opamp resource to use.
116 * @param[in] bad_arg_error The driver-specific error that should be returned if an invalid pin is specified
117 * @param[in] vin_p Non-inverting input pin. Must be specified.
118 * @param[in] vin_m Inverting input pin. May be NC.
119 * @param[in] vout Opamp output pin (analog). May be NC. Generally not specified in combination with comp_out
120 * @param[in] comp_out Comparator output pin (digital). May be NC. Generally not specified in combination with vout
121 * @return Whether the init operation succeeded.
122 */
123 cy_rslt_t _cyhal_opamp_init_common(cyhal_resource_inst_t* rsc, cy_rslt_t bad_arg_error, cyhal_gpio_t vin_p, cyhal_gpio_t vin_m, cyhal_gpio_t vout, cyhal_gpio_t comp_out);
124
125 /**
126 * Converts a HAL power level enum to a PDL-level opamp power enum value
127 *
128 * @param[in] hal_power power level as a HAL enum value
129 * @return the equivalent pdl-level enum value
130 */
131 uint32_t _cyhal_opamp_convert_power(cyhal_power_level_t hal_power);
132
133 #if defined(COMPONENT_CAT1)
134 /**
135 * Converts an opamp number into a PDL-level `cy_en_ctb_switch_register_sel_t` value.
136 *
137 * @param[in] oa_num the opamp number within its CTB(m)
138 * @return the PDL-level `cy_en_ctb_switch_register_sel_t` value.
139 */
_cyhal_opamp_convert_switch(uint8_t oa_num)140 __STATIC_INLINE cy_en_ctb_switch_register_sel_t _cyhal_opamp_convert_switch(uint8_t oa_num)
141 {
142 CY_ASSERT(oa_num < 2);
143 return (oa_num == 0) ? CY_CTB_SWITCH_OA0_SW : CY_CTB_SWITCH_OA1_SW;
144 }
145 #else
146 /**
147 * Converts an opamp number into a PDL-level `cy_en_ctb_opamp_sel_t` value.
148 *
149 * @param[in] oa_num the opamp number within its CTB(m)
150 * @return the PDL-level `cy_en_ctb_switch_register_sel_t` value.
151 */
_cyhal_opamp_convert_switch(uint8_t oa_num)152 __STATIC_INLINE cy_en_ctb_opamp_sel_t _cyhal_opamp_convert_switch(uint8_t oa_num)
153 {
154 CY_ASSERT(oa_num < 2);
155 return (oa_num == 0) ? CY_CTB_OPAMP_0 : CY_CTB_OPAMP_1;
156 }
157 #endif
158
159 /**
160 * Converts an opamp number into a PDL-level `cy_en_ctb_opamp_sel` value.
161 *
162 * @param[in] oa_num the opamp number within its CTB(m)
163 * @return the PDL-level `cy_en_ctb_opamp_sel` value.
164 */
_cyhal_opamp_convert_sel(uint8_t oa_num)165 __STATIC_INLINE cy_en_ctb_opamp_sel_t _cyhal_opamp_convert_sel(uint8_t oa_num)
166 {
167 CY_ASSERT(oa_num < 2);
168 return (oa_num == 0) ? CY_CTB_OPAMP_0 : CY_CTB_OPAMP_1;
169 }
170
171 /**
172 * Opens or closes the isolation switch if an opamp requires it
173 *
174 * @param[in] oa_num The opamp number within its CTB(m)
175 * @param[in] close Whether to close (true) or open (false) the switch
176 */
_cyhal_opamp_set_isolation_switch(uint8_t oa_num,CTBM_Type * base,bool close)177 __STATIC_INLINE void _cyhal_opamp_set_isolation_switch(uint8_t oa_num, CTBM_Type *base, bool close)
178 {
179 #if defined(COMPONENT_CAT1)
180 if(0u == oa_num)
181 {
182 // OA0 has an additional isolation switch (CIS) on its vplus line
183 Cy_CTB_SetAnalogSwitch(base, CY_CTB_SWITCH_CTD_SW, CY_CTB_SW_CTD_CHOLD_OA0_POS_ISOLATE_MASK,
184 close ? CY_CTB_SWITCH_CLOSE : CY_CTB_SWITCH_OPEN);
185 }
186 #else
187 // These devices don't have the isolation switch
188 CY_UNUSED_PARAMETER(oa_num);
189 CY_UNUSED_PARAMETER(base);
190 CY_UNUSED_PARAMETER(close);
191 #endif
192 }
193
194
195 #endif // _CYHAL_DRIVER_AVAILABLE_COMP_CTB
196
197 #if defined(__cplusplus)
198 }
199 #endif
200
201 #endif // _CYHAL_DRIVER_AVAILABLE_PASS
202