1 /***************************************************************************//**
2 * \file cy_sar2.c
3 * \version 1.1
4 *
5 * Provides API implementation of the SAR2 Driver.
6 *
7 *******************************************************************************
8 * \copyright
9 * (c) (2022), Cypress Semiconductor Corporation (an Infineon company) or
10 * an affiliate of Cypress Semiconductor Corporation. All rights reserved.
11 *******************************************************************************
12 * You may use this file only in accordance with the license, terms, conditions,
13 * disclaimers, and limitations in the end user license agreement accompanying
14 * the software package with which this file was provided.
15 *******************************************************************************/
16
17 #include "cy_sar2.h"
18
19 #if defined (CY_IP_MXS40EPASS_ESAR)
20
21 CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 10.8', 6, \
22 'Checked manually. Type cast to int8_t made intentionally.')
23
24 #define GET_SFLASH_VALUE(x) CY_GET_REG16(x)
25 #define GET_TRIM_VALUE(x) (GET_SFLASH_VALUE(x) & 0xFFFFu)
26
27 #define CY_SAR2_DIODE_COLD(t) (((t) == CY_SAR2_VDDA_2_7V_TO_4_5V) ? \
28 (SFLASH->EPASS_TEMP_TRIM_DIODE_COLDSORT) : (SFLASH->EPASS_TEMP_TRIM_DIODE_COLDSORT_5V))
29
30 #define CY_SAR2_DIODE_ROOM(t) (((t) == CY_SAR2_VDDA_2_7V_TO_4_5V) ? \
31 (SFLASH->EPASS_TEMP_TRIM_DIODE_ROOMSORT) : (SFLASH->EPASS_TEMP_TRIM_DIODE_ROOMSORT_5V))
32
33 #define CY_SAR2_DIODE_HOT(t) (((t) == CY_SAR2_VDDA_2_7V_TO_4_5V) ? \
34 (SFLASH->EPASS_TEMP_TRIM_DIODE_HOTCLASS) : (SFLASH->EPASS_TEMP_TRIM_DIODE_HOTCLASS_5V))
35
36 #define CY_SAR2_VBG_COLD(t) (((t) == CY_SAR2_VDDA_2_7V_TO_4_5V) ? \
37 (SFLASH->EPASS_TEMP_TRIM_VBG_COLDSORT) : (SFLASH->EPASS_TEMP_TRIM_VBG_COLDSORT_5V))
38
39 #define CY_SAR2_VBG_ROOM(t) (((t) == CY_SAR2_VDDA_2_7V_TO_4_5V) ? \
40 (SFLASH->EPASS_TEMP_TRIM_VBG_ROOMSORT) : (SFLASH->EPASS_TEMP_TRIM_VBG_ROOMSORT_5V))
41
42 #define CY_SAR2_VBG_HOT(t) (((t) == CY_SAR2_VDDA_2_7V_TO_4_5V) ? \
43 (SFLASH->EPASS_TEMP_TRIM_VBG_HOTCLASS) : (SFLASH->EPASS_TEMP_TRIM_VBG_HOTCLASS_5V))
44
45 typedef struct {
46 double hotValue; /**< The PASS hot temperature reading */
47 double roomValue; /**< The PASS room temperature reading */
48 double coldValue; /**< The PASS cold temperature reading */
49 } cy_stc_sar2_temp_sflash_data_t;
50
51
52 /*******************************************************************************
53 * Function Name: Cy_SAR2_Init
54 ****************************************************************************//**
55 *
56 * Initializes the SAR2 block.
57 *
58 * \param base
59 * The pointer to the SAR ADC block instance.
60 *
61 * \param config
62 * The pointer to the configuration structure \ref cy_stc_sar2_config_t.
63 *
64 * \return
65 * \ref cy_en_sar2_status_t
66 *
67 *******************************************************************************/
Cy_SAR2_Init(PASS_SAR_Type * base,const cy_stc_sar2_config_t * config)68 cy_en_sar2_status_t Cy_SAR2_Init(PASS_SAR_Type * base, const cy_stc_sar2_config_t * config)
69 {
70 cy_en_sar2_status_t ret = CY_SAR2_SUCCESS;
71
72 if ((NULL != config) && (NULL != base))
73 {
74 base->PRECOND_CTL = _VAL2FLD(PASS_SAR_PRECOND_CTL_PRECOND_TIME, config->preconditionTime);
75
76 base->CTL = (_VAL2FLD(PASS_SAR_CTL_PWRUP_TIME, config->powerupTime) |
77 _BOOL2FLD(PASS_SAR_CTL_IDLE_PWRDWN, config->enableIdlePowerDown) |
78 _BOOL2FLD(PASS_SAR_CTL_MSB_STRETCH, config->msbStretchMode) |
79 _BOOL2FLD(PASS_SAR_CTL_HALF_LSB, config->enableHalfLsbConv) |
80 _BOOL2FLD(PASS_SAR_CTL_SARMUX_EN, config->sarMuxEnable) |
81 _BOOL2FLD(PASS_SAR_CTL_ADC_EN, config->adcEnable) |
82 _BOOL2FLD(PASS_SAR_CTL_ENABLED, config->sarIpEnable));
83
84 for (uint8_t chan = 0u; chan < CY_SAR2_CHAN_NUM(base); chan++)
85 {
86 const cy_stc_sar2_channel_config_t * locChanCfg = config->channelConfig[chan];
87
88 if (NULL != locChanCfg)
89 {
90 (void) Cy_SAR2_Channel_Init(base, chan, locChanCfg);
91 }
92 }
93 }
94 else
95 {
96 ret = CY_SAR2_BAD_PARAM;
97 }
98
99 return ret;
100 }
101
102 /*******************************************************************************
103 * Function Name: Cy_SAR2_Channel_Init
104 ****************************************************************************//**
105 *
106 * Initializes an SAR channel.
107 *
108 * \param base
109 * The pointer to the SAR instance.
110 *
111 * \param channel
112 * The channel number.
113 *
114 * \param channelConfig
115 * The pointer to the configuration structure \ref cy_stc_sar2_channel_config_t.
116 *
117 * \return
118 * \ref cy_en_sar2_status_t
119 *
120 *******************************************************************************/
Cy_SAR2_Channel_Init(PASS_SAR_Type * base,uint32_t channel,const cy_stc_sar2_channel_config_t * channelConfig)121 cy_en_sar2_status_t Cy_SAR2_Channel_Init(PASS_SAR_Type * base, uint32_t channel,
122 const cy_stc_sar2_channel_config_t * channelConfig)
123 {
124 cy_en_sar2_status_t ret = CY_SAR2_SUCCESS;
125
126 CY_ASSERT_L1(NULL != channelConfig);
127 CY_ASSERT_L1(CY_SAR2_CHAN_NUM_VALID(base, channel));
128
129 if (CY_SAR2_CHAN_NUM_VALID(base, channel))
130 {
131 /* First, disable the channel */
132 Cy_SAR2_Channel_Disable(base, channel);
133
134 /* Clear the whole interrupt flags */
135 Cy_SAR2_Channel_ClearInterrupt(base, channel, CY_SAR2_INTR);
136
137 SAR2_CH_TR_CTL(base, channel) =
138 (_VAL2FLD(PASS_SAR_CH_TR_CTL_SEL, channelConfig->triggerSelection) |
139 _VAL2FLD(PASS_SAR_CH_TR_CTL_PRIO, channelConfig->channelPriority) |
140 _VAL2FLD(PASS_SAR_CH_TR_CTL_PREEMPT_TYPE, channelConfig->preenptionType) |
141 _BOOL2FLD(PASS_SAR_CH_TR_CTL_GROUP_END, channelConfig->isGroupEnd) |
142 _BOOL2FLD(PASS_SAR_CH_TR_CTL_DONE_LEVEL, channelConfig->doneLevel));
143
144 SAR2_CH_SAMPLE_CTL(base, channel) =
145 (_VAL2FLD(PASS_SAR_CH_SAMPLE_CTL_PIN_ADDR, channelConfig->pinAddress) |
146 _VAL2FLD(PASS_SAR_CH_SAMPLE_CTL_PORT_ADDR, channelConfig->portAddress) |
147 _VAL2FLD(PASS_SAR_CH_SAMPLE_CTL_EXT_MUX_SEL, channelConfig->extMuxSelect) |
148 _BOOL2FLD(PASS_SAR_CH_SAMPLE_CTL_EXT_MUX_EN, channelConfig->extMuxEnable) |
149 _VAL2FLD(PASS_SAR_CH_SAMPLE_CTL_PRECOND_MODE, channelConfig->preconditionMode) |
150 _VAL2FLD(PASS_SAR_CH_SAMPLE_CTL_OVERLAP_DIAG, channelConfig->overlapDiagMode) |
151 _VAL2FLD(PASS_SAR_CH_SAMPLE_CTL_SAMPLE_TIME, channelConfig->sampleTime) |
152 _VAL2FLD(PASS_SAR_CH_SAMPLE_CTL_ALT_CAL, channelConfig->calibrationValueSelect));
153
154 SAR2_CH_POST_CTL(base, channel) =
155 (_VAL2FLD(PASS_SAR_CH_POST_CTL_POST_PROC, channelConfig->postProcessingMode) |
156 _VAL2FLD(PASS_SAR_CH_POST_CTL_LEFT_ALIGN, channelConfig->resultAlignment) |
157 _VAL2FLD(PASS_SAR_CH_POST_CTL_SIGN_EXT, channelConfig->signExtention) |
158 _VAL2FLD(PASS_SAR_CH_POST_CTL_RANGE_MODE, channelConfig->rangeDetectionMode));
159
160 if((channelConfig->postProcessingMode == CY_SAR2_POST_PROCESSING_MODE_AVG) ||
161 (channelConfig->postProcessingMode == CY_SAR2_POST_PROCESSING_MODE_AVG_RANGE))
162 {
163 SAR2_CH_POST_CTL(base, channel) |=
164 (_VAL2FLD(PASS_SAR_CH_POST_CTL_AVG_CNT, (channelConfig->averageCount - 1UL)) |
165 _VAL2FLD(PASS_SAR_CH_POST_CTL_SHIFT_R, channelConfig->rightShift));
166 }
167 else if (channelConfig->postProcessingMode == CY_SAR2_POST_PROCESSING_MODE_RANGE_PULSE)
168 {
169 SAR2_CH_POST_CTL(base, channel) |=
170 (_VAL2FLD(PASS_SAR_CH_POST_CTL_AVG_CNT, channelConfig->positiveReload) |
171 _VAL2FLD(PASS_SAR_CH_POST_CTL_SHIFT_R, channelConfig->negativeReload));
172 }
173 else if (channelConfig->postProcessingMode == CY_SAR2_POST_PROCESSING_MODE_NONE)
174 {
175 SAR2_CH_POST_CTL(base, channel) |=
176 (_VAL2FLD(PASS_SAR_CH_POST_CTL_SHIFT_R, channelConfig->rightShift));
177 }
178 else
179 {
180 /* Do not configure post processing options */
181 }
182
183 SAR2_CH_RANGE_CTL(base, channel) =
184 (_VAL2FLD(PASS_SAR_CH_RANGE_CTL_RANGE_LO, channelConfig->rangeDetectionLoThreshold) |
185 _VAL2FLD(PASS_SAR_CH_RANGE_CTL_RANGE_HI, channelConfig->rangeDetectionHiThreshold));
186
187 if (channelConfig->channelHwEnable)
188 {
189 Cy_SAR2_Channel_Enable(base, channel);
190 }
191
192 Cy_SAR2_Channel_SetInterruptMask(base, channel, channelConfig->interruptMask);
193 }
194 else
195 {
196 ret = CY_SAR2_BAD_PARAM;
197 }
198
199 return ret;
200 }
201
202 /*******************************************************************************
203 * Function Name: Cy_SAR2_Channel_DeInit
204 ****************************************************************************//**
205 *
206 * Stops and de-initializes the SAR channel register.
207 *
208 * \param base
209 * The pointer to the SAR instance.
210 *
211 * \param channel
212 * The channel number.
213 *
214 *******************************************************************************/
Cy_SAR2_Channel_DeInit(PASS_SAR_Type * base,uint32_t channel)215 void Cy_SAR2_Channel_DeInit(PASS_SAR_Type * base, uint32_t channel)
216 {
217 CY_ASSERT_L1(CY_SAR2_CHAN_NUM_VALID(base, channel));
218
219 SAR2_CH_TR_CTL(base, channel) = 0x800UL; /* TR_CTL default value */
220 Cy_SAR2_Channel_Disable(base, channel);
221
222 /* Clear interrupt mask */
223 Cy_SAR2_Channel_SetInterruptMask(base, channel, 0UL);
224 }
225
226 /*******************************************************************************
227 * Function Name: Cy_SAR2_Channel_GetResult
228 ****************************************************************************//**
229 *
230 * Returns the conversion result and status.
231 *
232 * \param base
233 * The pointer to an SAR instance.
234 *
235 * \param channel
236 * The channel number.
237 *
238 * \param status
239 * The pointer that will return measurement status bits ORed. The pointer can be
240 * NULL, then, s status is not returned.
241 *
242 * \return Conversion result.
243 *
244 *******************************************************************************/
Cy_SAR2_Channel_GetResult(PASS_SAR_Type * base,uint32_t channel,uint32_t * status)245 uint16_t Cy_SAR2_Channel_GetResult(PASS_SAR_Type * base, uint32_t channel, uint32_t * status)
246 {
247 CY_ASSERT_L1(CY_SAR2_CHAN_NUM_VALID(base, channel));
248
249 uint32_t value = base->CH[channel].RESULT;
250
251 if (NULL != status)
252 {
253 *status = value & (PASS_SAR_CH_RESULT_ABOVE_HI_MIR_Msk |
254 PASS_SAR_CH_RESULT_RANGE_INTR_MIR_Msk |
255 PASS_SAR_CH_RESULT_PULSE_INTR_MIR_Msk |
256 PASS_SAR_CH_RESULT_VALID_MIR_Msk);
257 }
258
259 return (uint16_t)_FLD2VAL(PASS_SAR_CH_RESULT_RESULT, value);
260 }
261
262 /*******************************************************************************
263 * Function Name: Cy_SAR2_Channel_GetWorkingData
264 ****************************************************************************//**
265 *
266 * Returns the working data and status.
267 *
268 * \param base
269 * The pointer to the SAR instance.
270 *
271 * \param channel
272 * The channel number.
273 *
274 * \param status
275 * The pointer that will return measurement status bits ORed. The pointer can be
276 * NULL, then, a status is not returned.
277 *
278 * \return Conversion result.
279 *
280 *******************************************************************************/
Cy_SAR2_Channel_GetWorkingData(PASS_SAR_Type * base,uint32_t channel,uint32_t * status)281 uint16_t Cy_SAR2_Channel_GetWorkingData(PASS_SAR_Type * base, uint32_t channel, uint32_t * status)
282 {
283 CY_ASSERT_L1(CY_SAR2_CHAN_NUM_VALID(base, channel));
284
285 uint32_t value = base->CH[channel].WORK;
286
287 if (NULL != status)
288 {
289 *status = value & (PASS_SAR_CH_RESULT_ABOVE_HI_MIR_Msk |
290 PASS_SAR_CH_RESULT_RANGE_INTR_MIR_Msk |
291 PASS_SAR_CH_RESULT_PULSE_INTR_MIR_Msk |
292 PASS_SAR_CH_RESULT_VALID_MIR_Msk);
293 }
294
295 return (uint16_t)_FLD2VAL(PASS_SAR_CH_RESULT_RESULT, value);
296 }
297
298 /*******************************************************************************
299 * Function Name: Cy_SAR2_Diag_Init
300 ****************************************************************************//**
301 *
302 * Initializes the diagnosis function.
303 *
304 * \param base
305 * The pointer to the SAR instance.
306 *
307 * \param diagConfig
308 * The pointer to the configuration structure \ref cy_stc_sar2_diag_config_t.
309 *
310 * \return
311 * \ref cy_en_sar2_status_t
312 *
313 *******************************************************************************/
Cy_SAR2_Diag_Init(PASS_SAR_Type * base,const cy_stc_sar2_diag_config_t * diagConfig)314 cy_en_sar2_status_t Cy_SAR2_Diag_Init(PASS_SAR_Type * base, const cy_stc_sar2_diag_config_t * diagConfig)
315 {
316 cy_en_sar2_status_t ret = CY_SAR2_SUCCESS;
317
318 if (NULL != diagConfig)
319 {
320 base->DIAG_CTL = _CLR_SET_FLD32U(base->DIAG_CTL, PASS_SAR_DIAG_CTL_DIAG_SEL, diagConfig->referenceSelect);
321 }
322 else
323 {
324 ret = CY_SAR2_BAD_PARAM;
325 }
326
327 return ret;
328 }
329
330 /*******************************************************************************
331 * Function Name: Cy_SAR2_SetDigitalCalibrationValue
332 ****************************************************************************//**
333 *
334 * Configure SAR ADC digital calibration value.
335 *
336 * \param base
337 * The pointer to the SAR instance.
338 *
339 * \param digCalibConfig
340 * The pointer to the configuration structure
341 * \ref cy_stc_sar2_digital_calibration_config_t.
342 *
343 * \return
344 * \ref cy_en_sar2_status_t
345 *
346 *******************************************************************************/
Cy_SAR2_SetDigitalCalibrationValue(PASS_SAR_Type * base,const cy_stc_sar2_digital_calibration_config_t * digCalibConfig)347 cy_en_sar2_status_t Cy_SAR2_SetDigitalCalibrationValue(PASS_SAR_Type * base,
348 const cy_stc_sar2_digital_calibration_config_t * digCalibConfig)
349 {
350 cy_en_sar2_status_t ret = CY_SAR2_BAD_PARAM;
351
352 if (NULL != digCalibConfig)
353 {
354 base->DIG_CAL = (_VAL2FLD(PASS_SAR_DIG_CAL_DOFFSET, digCalibConfig->offset) |
355 _VAL2FLD(PASS_SAR_DIG_CAL_DGAIN, digCalibConfig->gain));
356 ret = CY_SAR2_SUCCESS;
357 }
358
359 return ret;
360 }
361
362 /*******************************************************************************
363 * Function Name: Cy_SAR2_GetDigitalCalibrationValue
364 ****************************************************************************//**
365 *
366 * Gets the SAR ADC digital calibration value.
367 *
368 * \param base
369 * The pointer to the SAR instance.
370 *
371 * \param digCalibConfig
372 * The pointer to the output configuration structure
373 * \ref cy_stc_sar2_digital_calibration_config_t.
374 *
375 * \return
376 * \ref cy_en_sar2_status_t
377 *
378 *******************************************************************************/
Cy_SAR2_GetDigitalCalibrationValue(PASS_SAR_Type * base,cy_stc_sar2_digital_calibration_config_t * digCalibConfig)379 cy_en_sar2_status_t Cy_SAR2_GetDigitalCalibrationValue(PASS_SAR_Type * base,
380 cy_stc_sar2_digital_calibration_config_t * digCalibConfig)
381 {
382 cy_en_sar2_status_t ret = CY_SAR2_SUCCESS;
383
384 uint32_t digCal = base->DIG_CAL;
385 if (NULL != digCalibConfig)
386 {
387 digCalibConfig->offset = (uint16_t) _FLD2VAL(PASS_SAR_DIG_CAL_DOFFSET, digCal);
388 digCalibConfig->gain = (int8_t) _FLD2VAL(PASS_SAR_DIG_CAL_DGAIN, digCal);
389 }
390 else
391 {
392 ret = CY_SAR2_BAD_PARAM;
393 }
394
395 return ret;
396 }
397
398 /*******************************************************************************
399 * Function Name: Cy_SAR2_SetAltDigitalCalibrationValue
400 ****************************************************************************//**
401 *
402 * Configures an alternate SAR digital calibration value.
403 *
404 * \param base
405 * The pointer to the SAR instance.
406 *
407 * \param altDigCalibConfig
408 * The pointer to the configuration structure
409 * \ref cy_stc_sar2_digital_calibration_config_t.
410 *
411 * \return
412 * \ref cy_en_sar2_status_t
413 *
414 *******************************************************************************/
Cy_SAR2_SetAltDigitalCalibrationValue(PASS_SAR_Type * base,const cy_stc_sar2_digital_calibration_config_t * altDigCalibConfig)415 cy_en_sar2_status_t Cy_SAR2_SetAltDigitalCalibrationValue(PASS_SAR_Type * base,
416 const cy_stc_sar2_digital_calibration_config_t * altDigCalibConfig)
417 {
418 cy_en_sar2_status_t ret = CY_SAR2_SUCCESS;
419
420 if (NULL != altDigCalibConfig)
421 {
422 base->DIG_CAL_ALT = (_VAL2FLD(PASS_SAR_DIG_CAL_ALT_DOFFSET, altDigCalibConfig->offset) |
423 _VAL2FLD(PASS_SAR_DIG_CAL_ALT_DGAIN, altDigCalibConfig->gain));
424 }
425 else
426 {
427 ret = CY_SAR2_BAD_PARAM;
428 }
429
430 return ret;
431 }
432
433 /*******************************************************************************
434 * Function Name: Cy_SAR2_GetAltDigitalCalibrationValue
435 ****************************************************************************//**
436 *
437 * Gets an alternate SAR digital calibration value.
438 *
439 * \param base
440 * The pointer to the SAR instance.
441 *
442 * \param altDigCalibConfig
443 * The utput pointer to the configuration structure
444 * \ref cy_stc_sar2_digital_calibration_config_t.
445 *
446 * \return
447 * \ref cy_en_sar2_status_t
448 *
449 *******************************************************************************/
Cy_SAR2_GetAltDigitalCalibrationValue(PASS_SAR_Type * base,cy_stc_sar2_digital_calibration_config_t * altDigCalibConfig)450 cy_en_sar2_status_t Cy_SAR2_GetAltDigitalCalibrationValue(PASS_SAR_Type * base,
451 cy_stc_sar2_digital_calibration_config_t * altDigCalibConfig)
452 {
453 cy_en_sar2_status_t ret = CY_SAR2_SUCCESS;
454
455 uint32_t digCalAlt = base->DIG_CAL_ALT;
456 if (NULL != altDigCalibConfig)
457 {
458 altDigCalibConfig->offset = (uint16_t) _FLD2VAL(PASS_SAR_DIG_CAL_ALT_DOFFSET, digCalAlt);
459 altDigCalibConfig->gain = (int8_t) _FLD2VAL(PASS_SAR_DIG_CAL_ALT_DGAIN, digCalAlt);
460 }
461 else
462 {
463 ret = CY_SAR2_BAD_PARAM;
464 }
465
466 return ret;
467 }
468
469 /*******************************************************************************
470 * Function Name: Cy_SAR2_SetAnalogCalibrationValue
471 ****************************************************************************//**
472 *
473 * Configures an SAR analog calibration value.
474 *
475 * \param base
476 * The pointer to the SAR instance.
477 *
478 * \param analogCalibConfig
479 * The pointer to the configuration structure
480 * \ref cy_stc_sar2_analog_calibration_conifg_t.
481 *
482 * \return
483 * \ref cy_en_sar2_status_t
484 *
485 *******************************************************************************/
Cy_SAR2_SetAnalogCalibrationValue(PASS_SAR_Type * base,cy_stc_sar2_analog_calibration_conifg_t * analogCalibConfig)486 cy_en_sar2_status_t Cy_SAR2_SetAnalogCalibrationValue(PASS_SAR_Type * base,
487 cy_stc_sar2_analog_calibration_conifg_t * analogCalibConfig)
488 {
489 cy_en_sar2_status_t ret = CY_SAR2_SUCCESS;
490
491 if (NULL != analogCalibConfig)
492 {
493 base->ANA_CAL = (_VAL2FLD(PASS_SAR_ANA_CAL_AOFFSET, analogCalibConfig->offset) |
494 _VAL2FLD(PASS_SAR_ANA_CAL_AGAIN, analogCalibConfig->gain));
495 }
496 else
497 {
498 ret = CY_SAR2_BAD_PARAM;
499 }
500
501 return ret;
502 }
503
504 /*******************************************************************************
505 * Function Name: Cy_SAR2_GetAnalogCalibrationValue
506 ****************************************************************************//**
507 *
508 * Gets an SAR analog calibration value.
509 *
510 * \param base
511 * The pointer to the SAR instance.
512 *
513 * \param analogCalibConfig
514 * The utput pointer to the configuration structure
515 * \ref cy_stc_sar2_analog_calibration_conifg_t.
516 *
517 * \return
518 * \ref cy_en_sar2_status_t
519 *
520 *******************************************************************************/
Cy_SAR2_GetAnalogCalibrationValue(PASS_SAR_Type * base,cy_stc_sar2_analog_calibration_conifg_t * analogCalibConfig)521 cy_en_sar2_status_t Cy_SAR2_GetAnalogCalibrationValue(PASS_SAR_Type * base,
522 cy_stc_sar2_analog_calibration_conifg_t * analogCalibConfig)
523 {
524 cy_en_sar2_status_t ret = CY_SAR2_SUCCESS;
525
526 uint32_t anaCal = base->ANA_CAL;
527 if (NULL != analogCalibConfig)
528 {
529 analogCalibConfig->offset = (int8_t) _FLD2VAL(PASS_SAR_ANA_CAL_AOFFSET, anaCal);
530 analogCalibConfig->gain = (int8_t) _FLD2VAL(PASS_SAR_ANA_CAL_AGAIN, anaCal);
531 }
532 else
533 {
534 ret = CY_SAR2_BAD_PARAM;
535 }
536
537 return ret;
538 }
539
540 /*******************************************************************************
541 * Function Name: Cy_SAR2_SetAltAnalogCalibrationValue
542 ****************************************************************************//**
543 *
544 * Configures an alternate SAR analog calibration value.
545 *
546 * \param base
547 * The pointer to the SAR instance.
548 *
549 * \param altAnalogCalibConfig
550 * The pointer to the configuration structure
551 * \ref cy_stc_sar2_analog_calibration_conifg_t.
552 *
553 * \return
554 * \ref cy_en_sar2_status_t
555 *
556 *******************************************************************************/
Cy_SAR2_SetAltAnalogCalibrationValue(PASS_SAR_Type * base,cy_stc_sar2_analog_calibration_conifg_t * altAnalogCalibConfig)557 cy_en_sar2_status_t Cy_SAR2_SetAltAnalogCalibrationValue(PASS_SAR_Type * base,
558 cy_stc_sar2_analog_calibration_conifg_t * altAnalogCalibConfig)
559 {
560 cy_en_sar2_status_t ret = CY_SAR2_SUCCESS;
561
562 if (NULL != altAnalogCalibConfig)
563 {
564 base->ANA_CAL_ALT = (_VAL2FLD(PASS_SAR_ANA_CAL_ALT_AOFFSET, altAnalogCalibConfig->offset) |
565 _VAL2FLD(PASS_SAR_ANA_CAL_ALT_AGAIN, altAnalogCalibConfig->gain));
566 }
567 else
568 {
569 ret = CY_SAR2_BAD_PARAM;
570 }
571
572 return ret;
573 }
574
575 /*******************************************************************************
576 * Function Name: Cy_SAR2_GetAltAnalogCalibrationValue
577 ****************************************************************************//**
578 *
579 * Gets an alternate SAR analog calibration value.
580 *
581 * \param base
582 * The pointer to the SAR instance.
583 *
584 * \param altAnalogCalibConfig
585 * The utput pointer to the configuration structure
586 * \ref cy_stc_sar2_analog_calibration_conifg_t.
587 *
588 * \return
589 * \ref cy_en_sar2_status_t
590 *
591 *******************************************************************************/
Cy_SAR2_GetAltAnalogCalibrationValue(PASS_SAR_Type * base,cy_stc_sar2_analog_calibration_conifg_t * altAnalogCalibConfig)592 cy_en_sar2_status_t Cy_SAR2_GetAltAnalogCalibrationValue(PASS_SAR_Type * base,
593 cy_stc_sar2_analog_calibration_conifg_t * altAnalogCalibConfig)
594 {
595 cy_en_sar2_status_t ret = CY_SAR2_SUCCESS;
596
597 uint32_t altAnaCal = base->ANA_CAL_ALT;
598 if (NULL != altAnalogCalibConfig)
599 {
600 altAnalogCalibConfig->offset = (int8_t) _FLD2VAL(PASS_SAR_ANA_CAL_AOFFSET, altAnaCal);
601 altAnalogCalibConfig->gain = (int8_t) _FLD2VAL(PASS_SAR_ANA_CAL_AGAIN, altAnaCal);
602 }
603 else
604 {
605 ret = CY_SAR2_BAD_PARAM;
606 }
607
608 return ret;
609 }
610
611 /*******************************************************************************
612 * Function Name: Cy_SAR2_SetDebugFreezeMode
613 ****************************************************************************//**
614 *
615 * Configures the debug pause feature.
616 *
617 * \param base
618 * The pointer to the PASS instance.
619 *
620 * \param debConfig
621 * The utput pointer to the configuration structure
622 * \ref cy_stc_sar2_debug_freeze_config_t.
623 *
624 * \return
625 * \ref cy_en_sar2_status_t
626 *
627 *******************************************************************************/
Cy_SAR2_SetDebugFreezeMode(PASS_EPASS_MMIO_Type * base,const cy_stc_sar2_debug_freeze_config_t * debConfig)628 cy_en_sar2_status_t Cy_SAR2_SetDebugFreezeMode(PASS_EPASS_MMIO_Type * base,
629 const cy_stc_sar2_debug_freeze_config_t * debConfig)
630 {
631 cy_en_sar2_status_t ret = CY_SAR2_SUCCESS;
632
633 uint32_t temp = 0UL;
634 if (NULL != debConfig)
635 {
636 temp |= (debConfig->enableFreezeAdc0) ? 1UL : 0UL;
637 temp |= (debConfig->enableFreezeAdc1) ? 2UL : 0UL;
638 temp |= (debConfig->enableFreezeAdc2) ? 4UL : 0UL;
639 temp |= (debConfig->enableFreezeAdc3) ? 8UL : 0UL;
640 base->PASS_CTL = _CLR_SET_FLD32U(base->PASS_CTL, PASS_EPASS_MMIO_PASS_CTL_DBG_FREEZE_EN, temp);
641 }
642 else
643 {
644 ret = CY_SAR2_BAD_PARAM;
645 }
646
647 return ret;
648 }
649
650 /*******************************************************************************
651 * Function Name: Cy_SAR2_SetGenericTriggerInput
652 ****************************************************************************//**
653 *
654 * Configures the generic trigger input selection.
655 *
656 * \param base
657 * The pointer to the PASS instance.
658 *
659 * \param numOfAdc
660 * The ADC channel number.
661 *
662 * \param triggerInputNumber
663 * The generic input trigger number to be set up.
664 *
665 * \param genericTriggerValue
666 * The generic input trigger to be used as a corresponding trigger input #.
667 *
668 * \return
669 * \ref cy_en_sar2_status_t
670 *
671 *******************************************************************************/
Cy_SAR2_SetGenericTriggerInput(PASS_EPASS_MMIO_Type * base,uint8_t numOfAdc,uint8_t triggerInputNumber,uint8_t genericTriggerValue)672 cy_en_sar2_status_t Cy_SAR2_SetGenericTriggerInput(PASS_EPASS_MMIO_Type * base, uint8_t numOfAdc,
673 uint8_t triggerInputNumber, uint8_t genericTriggerValue)
674 {
675 cy_en_sar2_status_t ret = CY_SAR2_SUCCESS;
676
677 if ((numOfAdc > PASS_SAR_ADC_NR) ||
678 (triggerInputNumber >= CY_SAR2_TR_IN_NUM) ||
679 (genericTriggerValue >= CY_SAR2_GEN_TR_IN_NUM))
680 {
681 ret = CY_SAR2_BAD_PARAM;
682 }
683 else
684 {
685 switch(triggerInputNumber)
686 {
687 case 0U:
688 base->SAR_TR_IN_SEL[numOfAdc] = _CLR_SET_FLD32U(base->SAR_TR_IN_SEL[numOfAdc],
689 PASS_EPASS_MMIO_SAR_TR_IN_SEL_IN0_SEL, genericTriggerValue);
690 break;
691 case 1U:
692 base->SAR_TR_IN_SEL[numOfAdc] = _CLR_SET_FLD32U(base->SAR_TR_IN_SEL[numOfAdc],
693 PASS_EPASS_MMIO_SAR_TR_IN_SEL_IN1_SEL, genericTriggerValue);
694 break;
695 case 2U:
696 base->SAR_TR_IN_SEL[numOfAdc] = _CLR_SET_FLD32U(base->SAR_TR_IN_SEL[numOfAdc],
697 PASS_EPASS_MMIO_SAR_TR_IN_SEL_IN2_SEL, genericTriggerValue);
698 break;
699 case 3U:
700 base->SAR_TR_IN_SEL[numOfAdc] = _CLR_SET_FLD32U(base->SAR_TR_IN_SEL[numOfAdc],
701 PASS_EPASS_MMIO_SAR_TR_IN_SEL_IN3_SEL, genericTriggerValue);
702 break;
703 case 4U:
704 base->SAR_TR_IN_SEL[numOfAdc] = _CLR_SET_FLD32U(base->SAR_TR_IN_SEL[numOfAdc],
705 PASS_EPASS_MMIO_SAR_TR_IN_SEL_IN4_SEL, genericTriggerValue);
706 break;
707 default:
708 /* Do nothing. */
709 break;
710 }
711 }
712
713 return ret;
714 }
715
716 /*******************************************************************************
717 * Function Name: Cy_SAR2_SetGenericTriggerOutput
718 ****************************************************************************//**
719 *
720 * Configures the generic output trigger selection.
721 *
722 * \param base
723 * The pointer to the PASS instance.
724 *
725 * \param numOfAdc
726 * The ADC channel number
727 *
728 * \param triggerOutputNumber
729 * The generic input trigger number to be set up.
730 *
731 * \param genericTriggerValue
732 * The generic input trigger to be used as a corresponding trigger input number.
733 *
734 * \return
735 * \ref cy_en_sar2_status_t
736 *
737 *******************************************************************************/
Cy_SAR2_SetGenericTriggerOutput(PASS_EPASS_MMIO_Type * base,uint8_t numOfAdc,uint8_t triggerOutputNumber,uint8_t genericTriggerValue)738 cy_en_sar2_status_t Cy_SAR2_SetGenericTriggerOutput(PASS_EPASS_MMIO_Type * base, uint8_t numOfAdc,
739 uint8_t triggerOutputNumber, uint8_t genericTriggerValue)
740 {
741 cy_en_sar2_status_t ret = CY_SAR2_SUCCESS;
742
743 if ((numOfAdc > PASS_SAR_ADC_NR) ||
744 (triggerOutputNumber >= CY_SAR2_TR_OUT_NUM) ||
745 (genericTriggerValue >= CY_SAR2_GEN_TR_OUT_NUM))
746 {
747 ret = CY_SAR2_BAD_PARAM;
748 }
749 else
750 {
751 switch(triggerOutputNumber)
752 {
753 case 0U:
754 base->SAR_TR_OUT_SEL[numOfAdc] = _CLR_SET_FLD32U(base->SAR_TR_OUT_SEL[numOfAdc],
755 PASS_EPASS_MMIO_SAR_TR_OUT_SEL_OUT0_SEL, genericTriggerValue);
756 break;
757 case 1U:
758 base->SAR_TR_OUT_SEL[numOfAdc] = _CLR_SET_FLD32U(base->SAR_TR_OUT_SEL[numOfAdc],
759 PASS_EPASS_MMIO_SAR_TR_OUT_SEL_OUT1_SEL, genericTriggerValue);
760 break;
761 default:
762 /* Do nothing. */
763 break;
764 }
765 }
766
767 return ret;
768 }
769
770 /*******************************************************************************
771 * Function Name: Cy_SAR2_CalculateDieTemperature
772 ****************************************************************************//**
773 *
774 * Calculates the internal temperature from ADC core using Vtemp.
775 * The API is implemented to calculate the temperature from the 2nd order
776 * equation of sort data with corrected class data. The API will convert sort data
777 * into [3][3] matrix and class data into [2][2] matrix.
778 *
779 * \param VDDARange
780 * VDDA voltage range, \ref cy_en_sar2_vdda_range_t.
781 *
782 * \param adcVtempRawValue
783 * The ADC counts the raw value of the temperature diode.
784 *
785 * \param adcVbgRawValue
786 * The ADC counts raw value of the Vbg voltage.
787 *
788 * \return
789 * Temperature Value
790 *
791 *******************************************************************************/
Cy_SAR2_CalculateDieTemperature(cy_en_sar2_vdda_range_t VDDARange,uint16_t adcVtempRawValue,uint16_t adcVbgRawValue)792 double Cy_SAR2_CalculateDieTemperature(cy_en_sar2_vdda_range_t VDDARange, uint16_t adcVtempRawValue,
793 uint16_t adcVbgRawValue)
794 {
795 double tempInDegreeC = 0.0;
796 cy_stc_sar2_temp_sflash_data_t adcTempValues;
797
798 /* Note: Temperature data read from sFLASH is multiple of 10. */
799 adcTempValues.coldValue = (((double)(-((float)(SFLASH->EPASS_TEMP_TRIM_TEMP_COLDSORT)))) / 10.0);
800 adcTempValues.roomValue = ((double)(SFLASH->EPASS_TEMP_TRIM_TEMP_ROOMSORT) / 10.0);
801 adcTempValues.hotValue = ((double)(SFLASH->EPASS_TEMP_TRIM_TEMP_HOTCLASS) / 10.0);
802
803 double determinant = 0.0;
804 double coefficientMatrixForSort[3][3] = {{0.0},{0.0},{0.0}};
805
806 double sortTempMatrixA[CY_SAR2_TEMP_MATRIX_SIZE][CY_SAR2_TEMP_MATRIX_SIZE];
807 double sortTempValueMatrixB[CY_SAR2_TEMP_MATRIX_SIZE][1];
808 double sortTempCoefficeintsX[CY_SAR2_TEMP_MATRIX_SIZE] = {0.0};
809
810 double coeffA;
811 double coeffB;
812 double coeffC;
813 double bSqrMin4ac = 0.0;
814 double tempRefValue = 0.0;
815 double tempScaleValue = 0.0;
816 double correctionFactor = 0.0;
817 double tempRootPos;
818 double tempRootNeg = 0.0;
819 double tempRangeOffset = (double) 10; /* relate to +/- 10 degC */
820 bool recalculate;
821
822 /***************************************************************************
823 * Updates the class and sorts the matrix from the sFLASH values
824 **************************************************************************/
825
826 /* Update the sort temperature value matrix A */
827 sortTempMatrixA[0][0] = 1.0;
828 sortTempMatrixA[0][1] = adcTempValues.coldValue;
829 sortTempMatrixA[0][2] = pow(adcTempValues.coldValue, 2.0);
830 sortTempMatrixA[1][0] = 1.0;
831 sortTempMatrixA[1][1] = adcTempValues.roomValue;
832 sortTempMatrixA[1][2] = pow(adcTempValues.roomValue, 2.0);
833 sortTempMatrixA[2][0] = 1.0;
834 sortTempMatrixA[2][1] = adcTempValues.hotValue;
835 sortTempMatrixA[2][2] = pow(adcTempValues.hotValue, 2.0);
836
837 /* Update the sort temperature adc value matrix B */
838 sortTempValueMatrixB[0][0] = (double)CY_SAR2_DIODE_COLD(VDDARange);
839 sortTempValueMatrixB[1][0] = (double)CY_SAR2_DIODE_ROOM(VDDARange);
840 sortTempValueMatrixB[2][0] = (double)CY_SAR2_DIODE_HOT(VDDARange);
841
842 /***************************************************************************
843 * Gets the 2nd order coefficient for the sort value matrix
844 **************************************************************************/
845
846 /* Get the determinant of sort temperature matrix A */
847 for(uint8_t i = 0U; i < CY_SAR2_TEMP_MATRIX_SIZE; i++)
848 {
849 determinant = determinant + (sortTempMatrixA[0][i]*(sortTempMatrixA[1U][(i+1U)%3U]*sortTempMatrixA[2U][(i+2U)%3U] -
850 sortTempMatrixA[1U][(i+2U)%3U]*sortTempMatrixA[2U][(i+1U)%3U]));
851 }
852
853 /* Get the inverse of sort temperature matrix A */
854 for(uint8_t i = 0U; i < CY_SAR2_TEMP_MATRIX_SIZE; i++)
855 {
856 for(uint8_t j = 0U; j < CY_SAR2_TEMP_MATRIX_SIZE; j++)
857 {
858 coefficientMatrixForSort[i][j] = ((sortTempMatrixA[(i+1U)%3U][(j+1U)%3U] * sortTempMatrixA[(i+2U)%3U][(j+2U)%3U]) -
859 (sortTempMatrixA[(i+1U)%3U][(j+2U)%3U]*sortTempMatrixA[(i+2U)%3U][(j+1U)%3U]))/ determinant;
860 }
861 }
862 for(uint8_t i = 0U; i < CY_SAR2_TEMP_MATRIX_SIZE; i++)
863 {
864 for(uint8_t j = 0U; j < CY_SAR2_TEMP_MATRIX_SIZE; j++)
865 {
866 sortTempMatrixA[i][j] = coefficientMatrixForSort[j][i];
867 }
868 }
869
870 /* Calculate sort temperature coefficient matrix X = (invA)*B */
871 for(uint8_t i = 0U; i < CY_SAR2_TEMP_MATRIX_SIZE; i++)
872 {
873 for(uint8_t j = 0U; j < CY_SAR2_TEMP_MATRIX_SIZE; j++)
874 {
875 sortTempCoefficeintsX[i] += (sortTempValueMatrixB[j][0]*sortTempMatrixA[i][j]);
876 }
877 }
878
879 /***************************************************************************
880 * Gets the temperature value from the 2nd order equation
881 **************************************************************************/
882
883 /* Rearrange the coefficients for the predicted temperature formula */
884 coeffA = sortTempCoefficeintsX[2];
885 coeffB = sortTempCoefficeintsX[1];
886 coeffC = sortTempCoefficeintsX[0];
887
888 /* -40degC -- SORT2, 27degC -- SORT3, 130degC -- CHI and by default reference value is SORT3 */
889 tempRefValue = (double)(CY_SAR2_VBG_ROOM(VDDARange));
890
891 do {
892 recalculate = false;
893
894 /* Calculate the correction factor (k) to remove the dependency of the ADC on the reference voltage */
895 correctionFactor = (tempRefValue) / ((double)(adcVbgRawValue));
896
897 /* Scale the data in raw with k */
898 tempScaleValue = (correctionFactor) * ((double)(adcVtempRawValue));
899
900 /* Calculate the predicted temperature */
901 bSqrMin4ac = (double) ( pow(coeffB, 2.0)) - (((4.0)*(coeffA))*(coeffC - tempScaleValue));
902 CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 10.3', 2, 'Intentional typecast of bSqrMin4ac to uint32_t ')
903 tempRootNeg = ((-coeffB)-((double)sqrtf(bSqrMin4ac))) / ((2.0)*(coeffA));
904 tempRootPos = ((-coeffB)+((double)sqrtf(bSqrMin4ac))) / ((2.0)*(coeffA));
905 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 10.3')
906 /* Select the root that lies between the Hot and Cold temperature sort values [-40 degC, 150 degC] */
907 if((tempRootPos < (adcTempValues.hotValue)) && (tempRootPos > (adcTempValues.coldValue)))
908 {
909 /* The temperature value is positive root of the curve */
910 tempInDegreeC = tempRootPos;
911 }
912 else if((tempRootNeg < (adcTempValues.hotValue)) && (tempRootNeg > (adcTempValues.coldValue)))
913 {
914 /* The temperature value is the negative root of the curve */
915 tempInDegreeC = tempRootNeg;
916 }
917 else
918 {
919 /* The Apt value is not found */
920 tempInDegreeC = 0.0;
921 }
922
923 /* Check for the close proximity of calculated temperature with the reference temperature values */
924 if (tempInDegreeC <= ((adcTempValues.coldValue) + tempRangeOffset))
925 {
926 /* Use the SORT2 value to scale the measured temperature */
927 tempRefValue = (double)(CY_SAR2_VBG_COLD(VDDARange));
928 recalculate = true;
929 }
930 else if (tempInDegreeC >= ((adcTempValues.hotValue) - tempRangeOffset))
931 {
932 /* Use the CHI value to scale the measured temperature */
933 tempRefValue = (double)(CY_SAR2_VBG_HOT(VDDARange));
934 recalculate = true;
935 }
936 else if ((tempInDegreeC <= ((adcTempValues.roomValue) + tempRangeOffset))
937 && (tempInDegreeC >= ((adcTempValues.roomValue) - tempRangeOffset)))
938 {
939 /* Use the SORT3 value to scale the measured temperature */
940 tempRefValue = (double)(CY_SAR2_VBG_ROOM(VDDARange));
941 }
942 else
943 {
944 /* Do nothing */
945 }
946 } while (recalculate == true);
947
948 return tempInDegreeC;
949 }
950
951 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 10.8')
952
953 #endif /* CY_IP_MXS40EPASS_ESAR */
954