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