1 /***************************************************************************//**
2 * \file cy_csd.c
3 * \version 1.20.2
4 *
5 * The source file of the CSD driver.
6 *
7 ********************************************************************************
8 * \copyright
9 * Copyright 2018-2022 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, locks, and configures the CSD HW block.
43 *
44 * If the CSD HW block is already in use by other middleware or by
45 * the application program, the function
46 * returns the CY_CSD_LOCKED status and does not configure the CSD HW block.
47 *
48 * If the acquisition is successful, 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 * To capture the CSD block without its reconfiguration, use the
55 * Cy_CSD_Capture() function.
56 *
57 * \param base
58 * The pointer to a CSD HW block base address.
59 *
60 * \param config
61 * The pointer to a configuration structure that contains the initial
62 * configuration.
63 *
64 * \param key
65 * The ID of middleware or a user-level function to work with
66 * the specified CSD HW block.
67 *
68 * \param context
69 * The pointer to the context structure allocated by the user or middleware.
70 *
71 * \return
72 * Returns the operation result status (CSD status code).
73 * See \ref cy_en_csd_status_t.
74 *
75 *******************************************************************************/
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)76 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)
77 {
78 cy_en_csd_status_t csdStatus = CY_CSD_LOCKED;
79
80 if ((NULL == base) || (CY_CSD_NONE_KEY == key) || (NULL == config) || (NULL == context))
81 {
82 csdStatus = CY_CSD_BAD_PARAM;
83 }
84 else
85 {
86 if(CY_CSD_NONE_KEY == context->lockKey)
87 {
88 context->lockKey = key;
89 csdStatus = Cy_CSD_Configure(base, config, key, context);
90 }
91 }
92
93 return(csdStatus);
94 }
95
96
97 /*******************************************************************************
98 * Function Name: Cy_CSD_DeInit
99 ****************************************************************************//**
100 *
101 * Releases the CSD HW block previously captured and locked by the caller.
102 *
103 * If the CSD HW block is acquired by another caller or the block is in the
104 * busy state (performing scan or conversion), the de-initialization request
105 * is ignored and the corresponding status is returned.
106 *
107 * \param base
108 * Pointer to a CSD HW block base address.
109 *
110 * \param key
111 * The ID of middleware or a user-level function to work with
112 * the specified CSD HW block.
113 *
114 * \param context
115 * The pointer to the context structure allocated by the user or middleware.
116 *
117 * \return
118 * Returns the operation result status (CSD status code).
119 * See \ref cy_en_csd_status_t.
120 *
121 *******************************************************************************/
Cy_CSD_DeInit(const CSD_Type * base,cy_en_csd_key_t key,cy_stc_csd_context_t * context)122 cy_en_csd_status_t Cy_CSD_DeInit(const CSD_Type * base, cy_en_csd_key_t key, cy_stc_csd_context_t * context)
123 {
124 cy_en_csd_status_t csdStatus = CY_CSD_LOCKED;
125
126 if(key == context->lockKey)
127 {
128 if(CY_CSD_SUCCESS == Cy_CSD_GetConversionStatus(base, context))
129 {
130 context->lockKey = CY_CSD_NONE_KEY;
131 csdStatus = CY_CSD_SUCCESS;
132 }
133 else
134 {
135 csdStatus = CY_CSD_BUSY;
136 }
137 }
138
139 return(csdStatus);
140 }
141
142
143 /*******************************************************************************
144 * Function Name: Cy_CSD_Capture
145 ****************************************************************************//**
146 *
147 * Acquires and locks the CSD HW block without changing its configuration.
148 *
149 * If the CSD HW block is already in use by other middleware or by
150 * the application program, the function
151 * returns the CY_CSD_LOCKED status.
152 *
153 * \note This is a low-level function. Use the Cy_CSD_Init() function instead.
154 * The Cy_CSD_Capture() function is used by upper-level middleware to improve
155 * efficiency. It also can be used to implement specific use cases. If this
156 * function is used, configure the CSD block using the Cy_CSD_Configure()
157 * function.
158 *
159 * \param base
160 * The pointer to a CSD HW block base address.
161 *
162 * \param key
163 * The ID of middleware or a user-level function to work with
164 * the specified CSD HW block.
165 *
166 * \param context
167 * The pointer to the context structure allocated by the user or middleware.
168 *
169 * \return
170 * Returns the operation result status (CSD status code).
171 * See \ref cy_en_csd_status_t.
172 *
173 *******************************************************************************/
Cy_CSD_Capture(CSD_Type * base,cy_en_csd_key_t key,cy_stc_csd_context_t * context)174 cy_en_csd_status_t Cy_CSD_Capture(CSD_Type * base, cy_en_csd_key_t key, cy_stc_csd_context_t * context)
175 {
176 cy_en_csd_status_t csdStatus = CY_CSD_LOCKED;
177
178 if ((NULL == base) || (CY_CSD_NONE_KEY == key) || (NULL == context))
179 {
180 csdStatus = CY_CSD_BAD_PARAM;
181 }
182 else
183 {
184 if(CY_CSD_NONE_KEY == context->lockKey)
185 {
186 context->lockKey = key;
187 csdStatus = CY_CSD_SUCCESS;
188 }
189 }
190
191 return(csdStatus);
192 }
193
194
195 /*******************************************************************************
196 * Function Name: Cy_CSD_Configure
197 ****************************************************************************//**
198 *
199 * Sets configuration of all CSD HW block registers at once.
200 *
201 * This function writes configuration data into all CSD block registers
202 * (except read-only registers and the SEQ_START register) at once. Because the
203 * SEQ_START register is excluded from write, use the Cy_CSD_WriteReg()
204 * function to perform triggering state machine for scan or conversion.
205 *
206 * \param base
207 * The pointer to a CSD HW block base address.
208 *
209 * \param config
210 * The pointer to a configuration structure that contains initial configuration.
211 *
212 * \param key
213 * The ID of middleware or a user-level function to work with
214 * the specified CSD HW block.
215 *
216 * \param context
217 * The pointer to the context structure allocated by the user or middleware.
218 *
219 * \return
220 * Returns the operation result status (CSD status code).
221 * See \ref cy_en_csd_status_t.
222 *
223 *******************************************************************************/
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)224 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)
225 {
226 cy_en_csd_status_t csdStatus = CY_CSD_LOCKED;
227
228 if (key == CY_CSD_NONE_KEY)
229 {
230 csdStatus = CY_CSD_BAD_PARAM;
231 }
232 else
233 {
234 if(key == context->lockKey)
235 {
236 csdStatus = CY_CSD_SUCCESS;
237
238 base->CONFIG = config->config;
239 base->SPARE = config->spare;
240 base->INTR = config->intr;
241 base->INTR_SET = config->intrSet;
242 base->INTR_MASK = config->intrMask;
243 base->HSCMP = config->hscmp;
244 base->AMBUF = config->ambuf;
245 base->REFGEN = config->refgen;
246 base->CSDCMP = config->csdCmp;
247 base->SW_RES = config->swRes;
248 base->SENSE_PERIOD = config->sensePeriod;
249 base->SENSE_DUTY = config->senseDuty;
250 base->SW_HS_P_SEL = config->swHsPosSel;
251 base->SW_HS_N_SEL = config->swHsNegSel;
252 base->SW_SHIELD_SEL = config->swShieldSel;
253 base->SW_AMUXBUF_SEL = config->swAmuxbufSel;
254 base->SW_BYP_SEL = config->swBypSel;
255 base->SW_CMP_P_SEL = config->swCmpPosSel;
256 base->SW_CMP_N_SEL = config->swCmpNegSel;
257 base->SW_REFGEN_SEL = config->swRefgenSel;
258 base->SW_FW_MOD_SEL = config->swFwModSel;
259 base->SW_FW_TANK_SEL = config->swFwTankSel;
260 base->SW_DSI_SEL = config->swDsiSel;
261 base->IO_SEL = config->ioSel;
262 base->SEQ_TIME = config->seqTime;
263 base->SEQ_INIT_CNT = config->seqInitCnt;
264 base->SEQ_NORM_CNT = config->seqNormCnt;
265 base->ADC_CTL = config->adcCtl;
266 base->IDACA = config->idacA;
267 base->IDACB = config->idacB;
268
269 (void)config->intr;
270 }
271 }
272
273 return(csdStatus);
274 }
275
276
277 /*******************************************************************************
278 * Function Name: Cy_CSD_GetVrefTrim
279 ****************************************************************************//**
280 *
281 * Adjusts the provided reference voltage based on factory trimmed
282 * SFLASH Vref trim registers.
283 *
284 * This function is mainly used by CSDADC middleware only to get the most
285 * accurate reference voltage possible.
286 *
287 * \param referenceVoltage
288 * The reference voltage to trim.
289 *
290 * \return
291 * Returns a trimmed reference voltage.
292 *
293 *******************************************************************************/
Cy_CSD_GetVrefTrim(uint32_t referenceVoltage)294 uint32_t Cy_CSD_GetVrefTrim(uint32_t referenceVoltage)
295 {
296 uint32_t vRef;
297 uint32_t nominalVoltage;
298 uint32_t registerVoltage;
299 uint32_t vRefTrimDelta;
300
301 /* Choose a Vref trim register */
302 if (referenceVoltage < CY_CSD_ADC_VREF_1P2)
303 {
304 nominalVoltage = CY_CSD_ADC_VREF_0P8;
305 registerVoltage = (uint32_t)(SFLASH_CSD0_ADC_VREF1_TRIM & SFLASH_CSDV2_CSD0_ADC_VREF1_VREF_HI_LEVELS_0P8_Msk) >>
306 SFLASH_CSDV2_CSD0_ADC_VREF1_VREF_HI_LEVELS_0P8_Pos;
307 }
308 else if (referenceVoltage < CY_CSD_ADC_VREF_1P6)
309 {
310 nominalVoltage = CY_CSD_ADC_VREF_1P2;
311 registerVoltage = (uint32_t)(SFLASH_CSD0_ADC_VREF0_TRIM & SFLASH_CSDV2_CSD0_ADC_VREF0_VREF_HI_LEVELS_1P2_Msk) >>
312 SFLASH_CSDV2_CSD0_ADC_VREF0_VREF_HI_LEVELS_1P2_Pos;
313 }
314 else if (referenceVoltage < CY_CSD_ADC_VREF_2P1)
315 {
316 nominalVoltage = CY_CSD_ADC_VREF_1P6;
317 registerVoltage = (uint32_t)(SFLASH_CSD0_ADC_VREF0_TRIM & SFLASH_CSDV2_CSD0_ADC_VREF0_VREF_HI_LEVELS_1P6_Msk) >>
318 SFLASH_CSDV2_CSD0_ADC_VREF0_VREF_HI_LEVELS_1P6_Pos;
319 }
320 else if (referenceVoltage < CY_CSD_ADC_VREF_2P6)
321 {
322 nominalVoltage = CY_CSD_ADC_VREF_2P1;
323 registerVoltage = (uint32_t)(SFLASH_CSD0_ADC_VREF1_TRIM & SFLASH_CSDV2_CSD0_ADC_VREF1_VREF_HI_LEVELS_2P1_Msk) >>
324 SFLASH_CSDV2_CSD0_ADC_VREF1_VREF_HI_LEVELS_2P1_Pos;
325 }
326 else
327 {
328 nominalVoltage = CY_CSD_ADC_VREF_2P6;
329 registerVoltage = (uint32_t)(SFLASH_CSD0_ADC_VREF2_TRIM & SFLASH_CSDV2_CSD0_ADC_VREF2_VREF_HI_LEVELS_2P6_Msk) >>
330 SFLASH_CSDV2_CSD0_ADC_VREF2_VREF_HI_LEVELS_2P6_Pos;
331 }
332
333 vRef = (referenceVoltage * registerVoltage) / nominalVoltage;
334
335 /* Calculate deviation of the trim register */
336 if (vRef > referenceVoltage)
337 {
338 vRefTrimDelta = vRef - referenceVoltage;
339 }
340 else
341 {
342 vRefTrimDelta = referenceVoltage - vRef;
343 }
344 vRefTrimDelta = (vRefTrimDelta * CY_CSDADC_PERCENTAGE_100) / referenceVoltage;
345
346 /* Return input Vref if trim-value is not within the allowed range */
347 if (CY_CSDADC_VREF_TRIM_MAX_DEVIATION < vRefTrimDelta)
348 {
349 vRef = referenceVoltage;
350 }
351
352 return vRef;
353 }
354
355
356 /** \} group_csd_functions */
357
358 #if defined(__cplusplus)
359 }
360 #endif
361
362 #endif /* CY_IP_MXCSDV2 */
363
364
365 /* [] END OF FILE */
366