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