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