1 /***************************************************************************//**
2 * \file cy_csd.c
3 * \version 1.10.2
4 *
5 * The source file of the CSD driver.
6 *
7 ********************************************************************************
8 * \copyright
9 * Copyright 2018-2020 Cypress Semiconductor Corporation
10 * SPDX-License-Identifier: Apache-2.0
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *******************************************************************************/
24
25 #include "cy_device.h"
26
27 #if defined (CY_IP_MXCSDV2)
28
29 #include <stdint.h>
30 #include "cy_syslib.h"
31 #include "cy_csd.h"
32
33 /**
34 * \addtogroup group_csd_functions
35 * \{
36 */
37
38 /*******************************************************************************
39 * Function Name: Cy_CSD_Init
40 ****************************************************************************//**
41 *
42 * Acquires and locks the CSD HW block and configures it.
43 *
44 * If the CSD HW block is already in use by other middleware or by
45 * the application program, then the function
46 * returns the CY_CSD_LOCKED status and does not configure the CSD HW block.
47 *
48 * In case of successful acquisition, this function writes configuration data
49 * into all CSD HW block registers (except read-only registers and SEQ_START
50 * register) at once. Because the SEQ_START register is excluded from write,
51 * use the Cy_CSD_WriteReg() function to trigger the state machine
52 * for scan or conversion.
53 *
54 * \param base
55 * Pointer to a CSD HW block base address.
56 *
57 * \param config
58 * The pointer to a configuration structure that contains the initial
59 * configuration.
60 *
61 * \param key
62 * An ID of middleware or user-level function that is going to work with
63 * the specified CSD HW block.
64 *
65 * \param context
66 * The pointer to the context structure allocated by a user or middleware.
67 *
68 * \return
69 * Returns an operation result status (CSD status code).
70 * See \ref cy_en_csd_status_t.
71 *
72 *******************************************************************************/
Cy_CSD_Init(CSD_Type * base,cy_stc_csd_config_t const * config,cy_en_csd_key_t key,cy_stc_csd_context_t * context)73 cy_en_csd_status_t Cy_CSD_Init(CSD_Type * base, cy_stc_csd_config_t const * config, cy_en_csd_key_t key, cy_stc_csd_context_t * context)
74 {
75 cy_en_csd_status_t csdStatus = CY_CSD_LOCKED;
76
77 if ((NULL == base) || (CY_CSD_NONE_KEY == key) || (NULL == config) || (NULL == context))
78 {
79 csdStatus = CY_CSD_BAD_PARAM;
80 }
81 else
82 {
83 if(CY_CSD_NONE_KEY == context->lockKey)
84 {
85 context->lockKey = key;
86 csdStatus = Cy_CSD_Configure(base, config, key, context);
87 }
88 }
89
90 return(csdStatus);
91 }
92
93
94 /*******************************************************************************
95 * Function Name: Cy_CSD_DeInit
96 ****************************************************************************//**
97 *
98 * Releases the CSD HW block previously captured and locked by the caller.
99 *
100 * If the CSD HW block is acquired by another caller or the block is in the
101 * busy state (performing scan or conversion), the de-initialization request
102 * is ignored and the corresponding status is returned.
103 *
104 * \param base
105 * Pointer to a CSD HW block base address.
106 *
107 * \param key
108 * An ID of middleware or user-level function that is going to work with
109 * a specified CSD HW block.
110 *
111 * \param context
112 * The pointer to the context structure allocated by a user or middleware.
113 *
114 * \return
115 * Returns an operation result status (CSD status code).
116 * See \ref cy_en_csd_status_t.
117 *
118 *******************************************************************************/
Cy_CSD_DeInit(const CSD_Type * base,cy_en_csd_key_t key,cy_stc_csd_context_t * context)119 cy_en_csd_status_t Cy_CSD_DeInit(const CSD_Type * base, cy_en_csd_key_t key, cy_stc_csd_context_t * context)
120 {
121 cy_en_csd_status_t csdStatus = CY_CSD_LOCKED;
122
123 if(key == context->lockKey)
124 {
125 if(CY_CSD_SUCCESS == Cy_CSD_GetConversionStatus(base, context))
126 {
127 context->lockKey = CY_CSD_NONE_KEY;
128 csdStatus = CY_CSD_SUCCESS;
129 }
130 else
131 {
132 csdStatus = CY_CSD_BUSY;
133 }
134 }
135
136 return(csdStatus);
137 }
138
139
140 /*******************************************************************************
141 * Function Name: Cy_CSD_Configure
142 ****************************************************************************//**
143 *
144 * Sets configuration of all CSD HW block registers at once.
145 *
146 * This function writes configuration data into all CSD block registers
147 * (except read-only registers and the SEQ_START register) at once. Because the
148 * SEQ_START register is excluded from write, use the Cy_CSD_WriteReg()
149 * function to perform triggering state machine for scan or conversion.
150 *
151 * \param base
152 * Pointer to a CSD HW block base address.
153 *
154 * \param config
155 * The pointer to a configuration structure that contains initial configuration.
156 *
157 * \param key
158 * An ID of middleware or user-level function that is going to work with
159 * the specified CSD HW block.
160 *
161 * \param context
162 * The pointer to the context structure allocated by a user or middleware.
163 *
164 * \return
165 * Returns an operation result status (CSD status code).
166 * See \ref cy_en_csd_status_t.
167 *
168 *******************************************************************************/
Cy_CSD_Configure(CSD_Type * base,const cy_stc_csd_config_t * config,cy_en_csd_key_t key,const cy_stc_csd_context_t * context)169 cy_en_csd_status_t Cy_CSD_Configure(CSD_Type * base, const cy_stc_csd_config_t * config, cy_en_csd_key_t key, const cy_stc_csd_context_t * context)
170 {
171 cy_en_csd_status_t csdStatus = CY_CSD_LOCKED;
172
173 if (key == CY_CSD_NONE_KEY)
174 {
175 csdStatus = CY_CSD_BAD_PARAM;
176 }
177 else
178 {
179 if(key == context->lockKey)
180 {
181 csdStatus = CY_CSD_SUCCESS;
182
183 base->CONFIG = config->config;
184 base->SPARE = config->spare;
185 base->INTR = config->intr;
186 base->INTR_SET = config->intrSet;
187 base->INTR_MASK = config->intrMask;
188 base->HSCMP = config->hscmp;
189 base->AMBUF = config->ambuf;
190 base->REFGEN = config->refgen;
191 base->CSDCMP = config->csdCmp;
192 base->SW_RES = config->swRes;
193 base->SENSE_PERIOD = config->sensePeriod;
194 base->SENSE_DUTY = config->senseDuty;
195 base->SW_HS_P_SEL = config->swHsPosSel;
196 base->SW_HS_N_SEL = config->swHsNegSel;
197 base->SW_SHIELD_SEL = config->swShieldSel;
198 base->SW_AMUXBUF_SEL = config->swAmuxbufSel;
199 base->SW_BYP_SEL = config->swBypSel;
200 base->SW_CMP_P_SEL = config->swCmpPosSel;
201 base->SW_CMP_N_SEL = config->swCmpNegSel;
202 base->SW_REFGEN_SEL = config->swRefgenSel;
203 base->SW_FW_MOD_SEL = config->swFwModSel;
204 base->SW_FW_TANK_SEL = config->swFwTankSel;
205 base->SW_DSI_SEL = config->swDsiSel;
206 base->IO_SEL = config->ioSel;
207 base->SEQ_TIME = config->seqTime;
208 base->SEQ_INIT_CNT = config->seqInitCnt;
209 base->SEQ_NORM_CNT = config->seqNormCnt;
210 base->ADC_CTL = config->adcCtl;
211 base->IDACA = config->idacA;
212 base->IDACB = config->idacB;
213
214 (void)config->intr;
215 }
216 }
217
218 return(csdStatus);
219 }
220
221
222 /*******************************************************************************
223 * Function Name: Cy_CSD_GetVrefTrim
224 ****************************************************************************//**
225 *
226 * Adjusts the provided reference voltage based on factory trimmed
227 * SFALSH Vref trim registers.
228 *
229 * This function is mainly used by CSDADC middleware only to get the most
230 * accurate reference voltage possible.
231 *
232 * \param referenceVoltage
233 * The reference voltage to trim.
234 *
235 * \return
236 * Returns a trimmed reference voltage.
237 *
238 *******************************************************************************/
Cy_CSD_GetVrefTrim(uint32_t referenceVoltage)239 uint32_t Cy_CSD_GetVrefTrim(uint32_t referenceVoltage)
240 {
241 uint32_t vRef;
242 uint32_t nominalVoltage;
243 uint32_t registerVoltage;
244 uint32_t vRefTrimDelta;
245
246 /* Choose a Vref trim register */
247 if (referenceVoltage < CY_CSD_ADC_VREF_1P2)
248 {
249 nominalVoltage = CY_CSD_ADC_VREF_0P8;
250 registerVoltage = (uint32_t)(SFLASH_CSD0_ADC_VREF1_TRIM & SFLASH_CSDV2_CSD0_ADC_VREF1_VREF_HI_LEVELS_0P8_Msk) >>
251 SFLASH_CSDV2_CSD0_ADC_VREF1_VREF_HI_LEVELS_0P8_Pos;
252 }
253 else if (referenceVoltage < CY_CSD_ADC_VREF_1P6)
254 {
255 nominalVoltage = CY_CSD_ADC_VREF_1P2;
256 registerVoltage = (uint32_t)(SFLASH_CSD0_ADC_VREF0_TRIM & SFLASH_CSDV2_CSD0_ADC_VREF0_VREF_HI_LEVELS_1P2_Msk) >>
257 SFLASH_CSDV2_CSD0_ADC_VREF0_VREF_HI_LEVELS_1P2_Pos;
258 }
259 else if (referenceVoltage < CY_CSD_ADC_VREF_2P1)
260 {
261 nominalVoltage = CY_CSD_ADC_VREF_1P6;
262 registerVoltage = (uint32_t)(SFLASH_CSD0_ADC_VREF0_TRIM & SFLASH_CSDV2_CSD0_ADC_VREF0_VREF_HI_LEVELS_1P6_Msk) >>
263 SFLASH_CSDV2_CSD0_ADC_VREF0_VREF_HI_LEVELS_1P6_Pos;
264 }
265 else if (referenceVoltage < CY_CSD_ADC_VREF_2P6)
266 {
267 nominalVoltage = CY_CSD_ADC_VREF_2P1;
268 registerVoltage = (uint32_t)(SFLASH_CSD0_ADC_VREF1_TRIM & SFLASH_CSDV2_CSD0_ADC_VREF1_VREF_HI_LEVELS_2P1_Msk) >>
269 SFLASH_CSDV2_CSD0_ADC_VREF1_VREF_HI_LEVELS_2P1_Pos;
270 }
271 else
272 {
273 nominalVoltage = CY_CSD_ADC_VREF_2P6;
274 registerVoltage = (uint32_t)(SFLASH_CSD0_ADC_VREF2_TRIM & SFLASH_CSDV2_CSD0_ADC_VREF2_VREF_HI_LEVELS_2P6_Msk) >>
275 SFLASH_CSDV2_CSD0_ADC_VREF2_VREF_HI_LEVELS_2P6_Pos;
276 }
277
278 vRef = (referenceVoltage * registerVoltage) / nominalVoltage;
279
280 /* Calculate deviation of the trim register */
281 if (vRef > referenceVoltage)
282 {
283 vRefTrimDelta = vRef - referenceVoltage;
284 }
285 else
286 {
287 vRefTrimDelta = referenceVoltage - vRef;
288 }
289 vRefTrimDelta = (vRefTrimDelta * CY_CSDADC_PERCENTAGE_100) / referenceVoltage;
290
291 /* Return input Vref if trim-value is not within the allowed range */
292 if (CY_CSDADC_VREF_TRIM_MAX_DEVIATION < vRefTrimDelta)
293 {
294 vRef = referenceVoltage;
295 }
296
297 return vRef;
298 }
299
300
301 /** \} group_csd_functions */
302
303 #if defined(__cplusplus)
304 }
305 #endif
306
307 #endif /* CY_IP_MXCSDV2 */
308
309
310 /* [] END OF FILE */
311