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