1 /***************************************************************************//**
2 * \file cy_sar.c
3 * \version 2.10
4 *
5 * Provides the public functions for the API for the SAR driver.
6 *
7 ********************************************************************************
8 * \copyright
9 * Copyright 2017-2021 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 express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *******************************************************************************/
24 #include "cy_sar.h"
25 
26 #ifdef CY_IP_MXS40PASS_SAR
27 
28 #if defined(__cplusplus)
29 extern "C" {
30 #endif
31 
32 CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 11.3', 81, \
33 'SAR_Type will typecast to either SAR_V1_Type or SAR_V2_Type but not both on PDL initialization based on the target device at compile time.')
34 
35 #define CHAN_NUM(chan)           ((chan) < CY_SAR_NUM_CHANNELS)
36 #define IS_RIGHT_ALIGN           (!_FLD2BOOL(SAR_SAMPLE_CTRL_LEFT_ALIGN, SAR_SAMPLE_CTRL(base)))
37 
38 #define CY_SAR_MASK                 (CY_SAR_SAR0 | \
39                                      CY_SAR_SAR1 | \
40                                      CY_SAR_SAR2 | \
41                                      CY_SAR_SAR3)
42 
43 #define IS_SAR_MASK_VALID(sarMask)  (0UL == ((sarMask) & ((uint32_t) ~CY_SAR_MASK)))
44 #define SCAN_CNT_MIN (1UL)
45 #define SCAN_CNT_MAX (256UL)
46 #define IS_SCAN_CNT_VALID(scanCnt) ((SCAN_CNT_MIN <= (scanCnt)) && ((scanCnt) <= SCAN_CNT_MAX))
47 
48 #define CY_SAR_TR_IN_0          (0UL)
49 #define CY_SAR_TR_IN_1          (1UL)
50 #define CY_SAR_TR_IN_2          (2UL)
51 #define CY_SAR_TR_IN_3          (3UL)
52 
53 static cy_stc_sar_state_backup_t enabledBeforeSleep[CY_SAR_INSTANCES] =
54 {
55     {0UL,0UL},{0UL,0UL}
56 };
57 
58 /* This array is used to calibrate the offset for each channel.
59 * At initialization, channels that are single-ended, signed, and with Vneg = Vref
60 * have an offset of -(2^12)/2 = -2048. All other channels have an offset of 0.
61 * The offset can be overridden using Cy_SAR_SetChannelOffset.
62 * The channel offsets are used by the Cy_SAR_CountsTo_Volts, Cy_SAR_CountsTo_mVolts, and
63 * Cy_SAR_CountsTo_uVolts functions to convert counts to voltage.
64 */
65 volatile int16_t Cy_SAR_offset[CY_SAR_NUM_CHANNELS][CY_SAR_INSTANCES];
66 
67 /* This array is used to calibrate the gain for each channel.
68 * It is set at initialization and the value depends on the SARADC resolution
69 * and voltage reference, 10*(2^12)/(2*Vref).
70 * The gain can be overridden using Cy_SAR_SetChannelGain.
71 * The channel gains are used by the Cy_SAR_CountsTo_Volts, Cy_SAR_CountsTo_mVolts and
72 * Cy_SAR_CountsTo_uVolts functions to convert counts to voltage.
73 */
74 volatile int32_t Cy_SAR_countsPer10Volt[CY_SAR_NUM_CHANNELS][CY_SAR_INSTANCES];
75 
76 /* Global variable to save internal states
77  * bit 0 - fifo enable for SAR0 instance
78  * bit 1 - fifo enable for SAR1 instance
79  * */
80 static uint32_t Cy_SAR_flags = 0UL;
81 
82 
83 /*******************************************************************************
84 * Function Name: Cy_SAR_CommonInit
85 ****************************************************************************//**
86 *
87 * Initialize common SAR configuration registers.
88 *
89 * \param base
90 * Pointer to structure describing PASS registers.
91 *
92 * \param trigConfig
93 * Pointer to structure containing configuration data.
94 * See \ref cy_stc_sar_common_config_t.
95 *
96 * \return
97 * - \ref CY_SAR_SUCCESS : initialization complete
98 * - \ref CY_SAR_BAD_PARAM : input pointers are null, initialization incomplete
99 *
100 * \funcusage
101 *
102 * \snippet sar/snippet/main.c SNIPPET_SAR_COMMON_INIT
103 *
104 *******************************************************************************/
Cy_SAR_CommonInit(PASS_Type * base,const cy_stc_sar_common_config_t * trigConfig)105 cy_en_sar_status_t Cy_SAR_CommonInit(PASS_Type * base, const cy_stc_sar_common_config_t  * trigConfig)
106 {
107     cy_en_sar_status_t result = CY_SAR_SUCCESS;
108 
109     if((!CY_PASS_V1) && (NULL != base) && (NULL != trigConfig))
110     {
111         uint32_t simultTrigSourceVal = CY_SAR_TR_IN_0;
112         bool simultTrigTimer = false;
113         uint32_t interruptState;
114 
115         CY_ASSERT_L3(IS_SAR_MASK_VALID(trigConfig->simultControl));
116         CY_ASSERT_L3(IS_SCAN_CNT_VALID(trigConfig->scanCount));
117 
118         /* Convert and check simultTrigSource value */
119         switch(trigConfig->simultTrigSource)
120         {
121         case CY_SAR_SAR0:
122             simultTrigSourceVal = CY_SAR_TR_IN_0;
123             break;
124 
125         case CY_SAR_SAR1:
126             simultTrigSourceVal = CY_SAR_TR_IN_1;
127             break;
128 
129         case CY_SAR_SAR2:
130             simultTrigSourceVal = CY_SAR_TR_IN_2;
131             break;
132 
133         case CY_SAR_SAR3:
134             simultTrigSourceVal = CY_SAR_TR_IN_3;
135             break;
136 
137         case CY_SAR_TIMER:
138             simultTrigTimer = true;
139             break;
140 
141         default:
142             /* Incorrect trigger source */
143             result = CY_SAR_BAD_PARAM;
144             break;
145         }
146 
147         if(CY_SAR_SUCCESS == result)
148         {
149             PASS_SAR_SIMULT_CTRL(base) = _VAL2FLD(PASS_V2_SAR_SIMULT_CTRL_SIMULT_HW_TR_EN, trigConfig->simultControl)                              |
150                                          _VAL2FLD(PASS_V2_SAR_SIMULT_CTRL_SIMULT_HW_TR_SRC, simultTrigSourceVal)                                   |
151                                         _BOOL2FLD(PASS_V2_SAR_SIMULT_CTRL_SIMULT_HW_TR_TIMER_SEL, simultTrigTimer)                                 |
152                                          _VAL2FLD(PASS_V2_SAR_SIMULT_CTRL_SIMULT_HW_TR_LEVEL, (uint32_t)(trigConfig->simultTrigEvent))             |
153                                          _VAL2FLD(PASS_V2_SAR_SIMULT_CTRL_SIMULT_HW_SYNC_TR, (uint32_t)(trigConfig->simultTrigSync))               |
154                                          _VAL2FLD(PASS_V2_SAR_SIMULT_CTRL_SIMULT_TR_SCAN_CNT_SEL, (uint32_t)(trigConfig->simultSamplesPerTrigger)) |
155                                          _VAL2FLD(PASS_V2_SAR_SIMULT_CTRL_SIMULT_EOS_INTR_SCAN_CNT_SEL, (uint32_t)(trigConfig->simultEOSIntrSelect));
156             PASS_SAR_TR_SCAN_CNT(base) = _VAL2FLD(PASS_V2_SAR_TR_SCAN_CNT_SCAN_CNT, trigConfig->scanCount - 1UL);
157 
158             interruptState = Cy_SysLib_EnterCriticalSection();
159             CY_REG32_CLR_SET(PASS_ANA_PWR_CFG(base), PASS_V2_ANA_PWR_CFG_PWR_UP_DELAY, trigConfig->pwrUpDelay);
160             Cy_SysLib_ExitCriticalSection(interruptState);
161         }
162     }
163     else
164     {
165         result = CY_SAR_BAD_PARAM;
166     }
167 
168     return result;
169 }
170 
171 /*******************************************************************************
172 * Function Name: Cy_SAR_Init
173 ****************************************************************************//**
174 *
175 * Initialize all SAR configuration registers.
176 * If routing is to be configured, all switches will be cleared before
177 * being initialized.
178 *
179 * \note If interleaved averaging mode is used, the Differential Result Format
180 *       should be the same as the Single-Ended Result Format. Otherwise, this
181 *       function will return CY_SAR_BAD_PARAM.
182 *
183 * \param base
184 * Pointer to structure describing SAR instance registers
185 *
186 * \param config
187 * Pointer to structure containing configuration data. See \ref cy_stc_sar_config_t
188 * and guidance in the \ref group_sar_initialization section.
189 *
190 * \return
191 * - \ref CY_SAR_SUCCESS : initialization complete successfully
192 * - \ref CY_SAR_BAD_PARAM : input pointers are null or some configuration
193                             setting is invalid, initialization incomplete.
194 *
195 * \funcusage \snippet sar/snippet/main.c SNIPPET_SAR_INIT_CUSTOM
196 *
197 *******************************************************************************/
Cy_SAR_Init(SAR_Type * base,const cy_stc_sar_config_t * config)198 cy_en_sar_status_t Cy_SAR_Init(SAR_Type * base, const cy_stc_sar_config_t * config)
199 {
200     cy_en_sar_status_t result = CY_SAR_BAD_PARAM;
201 
202     CY_ASSERT_L1(NULL != base);
203     CY_ASSERT_L1(NULL != config);
204 
205     if ((NULL != base) && (NULL != config))
206     {
207         /* If interleaved averaging mode is used, the Differential Result Format should be the same as the Single-Ended Result Format. */
208         if (((0UL != (config->sampleCtrl & SAR_V2_SAMPLE_CTRL_AVG_MODE_Msk)) ?
209            !((0UL != (config->sampleCtrl & SAR_V2_SAMPLE_CTRL_SINGLE_ENDED_SIGNED_Msk)) !=
210              (0UL != (config->sampleCtrl & SAR_V2_SAMPLE_CTRL_DIFFERENTIAL_SIGNED_Msk))) : true) &&
211         /* The FIFO is supported by PASS_ver2 only */
212             ((NULL != config->fifoCfgPtr) ? !CY_PASS_V1 : true) &&
213         /* The Clock selection CY_SAR_CLK_DEEPSLEEP is allowed for PASS_V2 only */
214             ((CY_SAR_CLK_DEEPSLEEP == config->clock) ? !CY_PASS_V1 : true))
215         {
216             uint32_t interruptState;
217             uint8_t chan;
218             bool vrefNegSelect;
219             bool singleEndedSigned;
220             bool chanSingleEnded;
221             int32_t defaultGain;
222 
223             CY_ASSERT_L2(CY_SAR_CTRL(config->ctrl));
224             CY_ASSERT_L2(CY_SAR_SAMPLE_CTRL(config->sampleCtrl));
225             CY_ASSERT_L2(CY_SAR_SAMPLE_TIME(config->sampleTime01));
226             CY_ASSERT_L2(CY_SAR_SAMPLE_TIME(config->sampleTime23));
227             CY_ASSERT_L3(CY_SAR_RANGECOND(config->rangeCond));
228             CY_ASSERT_L2(CY_SAR_INJMASK(config->chanEn));
229             CY_ASSERT_L2(CY_SAR_INTRMASK(config->intrMask));
230             CY_ASSERT_L2(CY_SAR_CHANMASK(config->satIntrMask));
231             CY_ASSERT_L2(CY_SAR_CHANMASK(config->rangeIntrMask));
232 
233             /* Set the REFBUF_EN bit as this is required for proper operation. */
234             SAR_CTRL(base) = (config->ctrl | SAR_CTRL_REFBUF_EN_Msk) & ~SAR_CTRL_ENABLED_Msk;
235             SAR_SAMPLE_CTRL(base) = config->sampleCtrl | SAR_SAMPLE_CTRL_EOS_DSI_OUT_EN_Msk; /* Set the EOS_DSI_OUT_EN bit so the EOS signal can be routed */
236             SAR_SAMPLE_TIME01(base) = config->sampleTime01;
237             SAR_SAMPLE_TIME23(base) = config->sampleTime23;
238             SAR_RANGE_THRES(base) = config->rangeThres;
239             SAR_RANGE_COND(base) = (uint32_t)config->rangeCond << SAR_RANGE_COND_RANGE_COND_Pos;
240             SAR_CHAN_EN(base) = _VAL2FLD(SAR_CHAN_EN_CHAN_EN, config->chanEn);
241 
242             /* Check whether NEG_SEL is set for VREF */
243             vrefNegSelect = ((uint32_t)CY_SAR_NEG_SEL_VREF == (config->ctrl & SAR_CTRL_NEG_SEL_Msk))? true : false;
244             /* Check whether single ended channels are set to signed */
245             singleEndedSigned = (SAR_SAMPLE_CTRL_SINGLE_ENDED_SIGNED_Msk == (config->sampleCtrl & SAR_SAMPLE_CTRL_SINGLE_ENDED_SIGNED_Msk)) ? true : false;
246             /* Calculate the default gain for all the channels in counts per 10 volts with rounding */
247             defaultGain = (int32_t)(uint16_t)CY_SYSLIB_DIV_ROUND((uint32_t)CY_SAR_WRK_MAX_12BIT * (uint32_t)CY_SAR_10MV_COUNTS, config->vrefMvValue * 2UL);
248 
249             for (chan = 0u; chan < CY_SAR_SEQ_NUM_CHANNELS; chan++)
250             {
251                 CY_ASSERT_L2(CY_SAR_CHAN_CONFIG(config->chanConfig[chan]));
252 
253                 SAR_CHAN_CONFIG(base, chan) = config->chanConfig[chan];
254 
255                 /* For signed single ended channels with NEG_SEL set to VREF,
256                  * set the offset to minus half scale to convert results to unsigned format */
257                 chanSingleEnded = (0UL == (config->chanConfig[chan] & (SAR_CHAN_CONFIG_DIFFERENTIAL_EN_Msk | SAR_CHAN_CONFIG_NEG_ADDR_EN_Msk))) ? true : false;
258                 if (chanSingleEnded && vrefNegSelect && singleEndedSigned)
259                 {
260                     Cy_SAR_offset[chan][CY_SAR_INSTANCE(base)] = (int16_t) (CY_SAR_WRK_MAX_12BIT / -2);
261                 }
262                 else
263                 {
264                     Cy_SAR_offset[chan][CY_SAR_INSTANCE(base)] = 0;
265                 }
266 
267                 Cy_SAR_countsPer10Volt[chan][CY_SAR_INSTANCE(base)] = defaultGain;
268             }
269 
270             SAR_INTR_MASK(base) = config->intrMask;
271             SAR_INTR(base) = config->intrMask;
272             SAR_SATURATE_INTR_MASK(base) = config->satIntrMask;
273             SAR_SATURATE_INTR(base) = config->satIntrMask;
274             SAR_RANGE_INTR_MASK(base) = config->rangeIntrMask;
275             SAR_RANGE_INTR(base) = config->rangeIntrMask;
276 
277             /* Set routing related registers if enabled */
278             if (true == config->configRouting)
279             {
280                 CY_ASSERT_L2(CY_SAR_SWITCHMASK(config->muxSwitch));
281                 CY_ASSERT_L2(CY_SAR_SQMASK(config->muxSwitchSqCtrl));
282 
283                 /* Clear out all the switches so that only the desired switches in the config structure are set. */
284                 SAR_MUX_SWITCH_CLEAR0(base) = CY_SAR_CLEAR_ALL_SWITCHES;
285 
286                 SAR_MUX_SWITCH0(base) = config->muxSwitch;
287                 SAR_MUX_SWITCH_SQ_CTRL(base) = config->muxSwitchSqCtrl;
288             }
289 
290             /* Set the Cap trim if it was trimmed out of range from sflash */
291             if ((CY_SAR_CAP_TRIM_MAX == SAR_ANA_TRIM0(base)) || (CY_SAR_CAP_TRIM_MIN == SAR_ANA_TRIM0(base)))
292             {
293                 SAR_ANA_TRIM0(base) = CY_SAR_CAP_TRIM;
294             }
295 
296             if (0UL != (CY_SAR_INJ_CHAN_MASK & config->chanEn))
297             {
298                 SAR_INJ_CHAN_CONFIG(base) = config->chanConfig[CY_SAR_INJ_CHANNEL];
299                 Cy_SAR_countsPer10Volt[CY_SAR_INJ_CHANNEL][CY_SAR_INSTANCE(base)] = defaultGain;
300             }
301 
302             if (NULL != config->fifoCfgPtr)
303             {
304                 uint32_t locLevel = config->fifoCfgPtr->level - 1UL; /* Convert the user value into the machine value */
305 
306                 Cy_SAR_flags |= CY_SAR_INSTANCE_MASK(base);
307 
308                 PASS_FIFO_CONFIG(base) = _BOOL2FLD(PASS_FIFO_V2_CONFIG_CHAN_ID_EN,        config->fifoCfgPtr->chanId) |
309                                          _BOOL2FLD(PASS_FIFO_V2_CONFIG_CHAIN_TO_NXT,      config->fifoCfgPtr->chainToNext) |
310                                          _BOOL2FLD(PASS_FIFO_V2_CONFIG_TR_INTR_CLR_RD_EN, config->fifoCfgPtr->clrTrIntrOnRead);
311 
312                 CY_ASSERT_L2(CY_SAR_IS_FIFO_LEVEL_VALID(locLevel));
313                 PASS_FIFO_LEVEL(base) = _VAL2FLD(PASS_FIFO_V2_LEVEL_LEVEL, locLevel);
314 
315                 interruptState = Cy_SysLib_EnterCriticalSection();
316 
317                 if (config->fifoCfgPtr->trOut)
318                 {
319                     PASS_SAR_TR_OUT_CTRL(CY_PASS_V2_ADDR) |= CY_SAR_INSTANCE_MASK(base);
320                 }
321                 else
322                 {
323                     PASS_SAR_TR_OUT_CTRL(CY_PASS_V2_ADDR) &= ~CY_SAR_INSTANCE_MASK(base);
324                 }
325 
326                 Cy_SysLib_ExitCriticalSection(interruptState);
327             }
328             else
329             {
330                 Cy_SAR_flags &= ~CY_SAR_INSTANCE_MASK(base);
331             }
332 
333             if (!CY_PASS_V1)
334             {
335                 uint32_t locReg;
336                 uint32_t locAndMask = ~(CY_SAR_INSTANCE_MASK(base) |
337                                        (CY_SAR_INSTANCE_MASK(base) << PASS_V2_SAR_OVR_CTRL_TR_SCAN_CNT_SEL_Pos) |
338                                        (CY_SAR_INSTANCE_MASK(base) << PASS_V2_SAR_OVR_CTRL_EOS_INTR_SCAN_CNT_SEL_Pos));
339                 uint32_t locOrMask = (config->trTimer ? CY_SAR_INSTANCE_MASK(base) : 0UL) |
340                                      (config->scanCnt ? (CY_SAR_INSTANCE_MASK(base) << PASS_V2_SAR_OVR_CTRL_TR_SCAN_CNT_SEL_Pos) : 0UL) |
341                                      (config->scanCntIntr ? (CY_SAR_INSTANCE_MASK(base) << PASS_V2_SAR_OVR_CTRL_EOS_INTR_SCAN_CNT_SEL_Pos) : 0UL);
342 
343                 interruptState = Cy_SysLib_EnterCriticalSection();
344 
345                 locReg = PASS_SAR_OVR_CTRL(CY_PASS_V2_ADDR);
346                 locReg &= locAndMask;
347                 locReg |= locOrMask;
348                 PASS_SAR_OVR_CTRL(CY_PASS_V2_ADDR) = locReg;
349 
350                 Cy_SysLib_ExitCriticalSection(interruptState);
351 
352                 CY_ASSERT_L3(CY_SAR_IS_CLK_VALID(config->clock));
353                 PASS_SAR_CLOCK_SEL(base) = _VAL2FLD(PASS_V2_SAR_CLOCK_SEL_CLOCK_SEL, config->clock);
354                 PASS_SAR_DPSLP_CTRL(base) = _BOOL2FLD(PASS_V2_SAR_DPSLP_CTRL_ENABLED, (CY_SAR_CLK_DEEPSLEEP == config->clock));
355             }
356 
357             result = CY_SAR_SUCCESS;
358         }
359     }
360 
361     return result;
362 }
363 
364 
365 /*******************************************************************************
366 * Function Name: Cy_SAR_DeInit
367 ****************************************************************************//**
368 *
369 * Reset SAR registers back to power on reset defaults.
370 *
371 * \if Cy_SAR_offset and Cy_SAR_countsPer10Volt arrays are NOT reset. \endif
372 *
373 * \param base
374 * Pointer to structure describing registers
375 *
376 * \param deInitRouting
377 * If true, all SARMUX switches are opened and switch control registers are reset
378 * to zero. If false, switch registers are untouched.
379 *
380 * \return
381 * - \ref CY_SAR_SUCCESS : de-initialization complete
382 * - \ref CY_SAR_BAD_PARAM : input pointers are null, de-initialization incomplete
383 *
384 * \funcusage
385 *
386 * \snippet sar/snippet/main.c SNIPPET_SAR_DEINIT
387 *
388 *******************************************************************************/
Cy_SAR_DeInit(SAR_Type * base,bool deInitRouting)389 cy_en_sar_status_t Cy_SAR_DeInit(SAR_Type * base, bool deInitRouting)
390 {
391     cy_en_sar_status_t result = CY_SAR_BAD_PARAM;
392 
393     CY_ASSERT_L1(NULL != base);
394 
395     if (NULL != base)
396     {
397         uint8_t chan;
398 
399         SAR_CTRL(base) = CY_SAR_DEINIT;
400         SAR_SAMPLE_CTRL(base) = CY_SAR_DEINIT;
401         SAR_SAMPLE_TIME01(base) = CY_SAR_SAMPLE_TIME_DEINIT;
402         SAR_SAMPLE_TIME23(base) = CY_SAR_SAMPLE_TIME_DEINIT;
403         SAR_RANGE_THRES(base) = CY_SAR_DEINIT;
404         SAR_RANGE_COND(base) = CY_SAR_DEINIT;
405         SAR_CHAN_EN(base) = CY_SAR_DEINIT;
406         for (chan = 0u; chan < CY_SAR_SEQ_NUM_CHANNELS; chan++)
407         {
408             SAR_CHAN_CONFIG(base, chan) = CY_SAR_DEINIT;
409         }
410         SAR_INJ_CHAN_CONFIG(base) = CY_SAR_DEINIT;
411         SAR_INTR_MASK(base) = CY_SAR_DEINIT;
412         SAR_SATURATE_INTR_MASK(base) = CY_SAR_DEINIT;
413         SAR_RANGE_INTR_MASK(base) = CY_SAR_DEINIT;
414         if (true == deInitRouting)
415         {
416             SAR_MUX_SWITCH_CLEAR0(base) = CY_SAR_CLEAR_ALL_SWITCHES;
417             SAR_MUX_SWITCH_DS_CTRL(base) = CY_SAR_DEINIT;
418             SAR_MUX_SWITCH_SQ_CTRL(base) = CY_SAR_DEINIT;
419         }
420 
421         if (!CY_PASS_V1)
422         {
423             uint32_t locAndMask = ~(CY_SAR_INSTANCE_MASK(base) |
424                                     (CY_SAR_INSTANCE_MASK(base) << PASS_V2_SAR_OVR_CTRL_TR_SCAN_CNT_SEL_Pos) |
425                                     (CY_SAR_INSTANCE_MASK(base) << PASS_V2_SAR_OVR_CTRL_EOS_INTR_SCAN_CNT_SEL_Pos));
426 
427             uint32_t interruptState = Cy_SysLib_EnterCriticalSection();
428 
429             PASS_SAR_OVR_CTRL(CY_PASS_V2_ADDR) &= locAndMask;
430             PASS_SAR_TR_OUT_CTRL(CY_PASS_V2_ADDR) &= ~CY_SAR_INSTANCE_MASK(base);
431 
432             Cy_SysLib_ExitCriticalSection(interruptState);
433 
434             if (0UL != (Cy_SAR_flags & CY_SAR_INSTANCE_MASK(base)))
435             {
436                 PASS_FIFO_CTRL(base) = CY_SAR_DEINIT; /* Disable first */
437                 PASS_FIFO_CONFIG(base) = CY_SAR_DEINIT;
438                 PASS_FIFO_LEVEL(base) = CY_SAR_DEINIT;
439                 Cy_SAR_flags &= ~CY_SAR_INSTANCE_MASK(base);
440             }
441 
442             PASS_SAR_DPSLP_CTRL(base) = CY_SAR_DEINIT;
443             PASS_SAR_CLOCK_SEL(base) = CY_SAR_DEINIT;
444         }
445 
446         result = CY_SAR_SUCCESS;
447     }
448 
449     return result;
450 }
451 
452 
453 /*******************************************************************************
454 * Function Name: Cy_SAR_Enable
455 ****************************************************************************//**
456 *
457 * Power up the SAR ADC subsystem block. The hardware is ready to use
458 * after 2 us, which is included in this function.
459 *
460 * \param base
461 * Pointer to structure describing registers
462 *
463 * \return None
464 *
465 *******************************************************************************/
Cy_SAR_Enable(SAR_Type * base)466 void Cy_SAR_Enable(SAR_Type *base)
467 {
468     if (!_FLD2BOOL(SAR_CTRL_ENABLED, SAR_CTRL(base)))
469     {
470         SAR_CTRL(base) |= SAR_CTRL_ENABLED_Msk;
471 
472         /* The block is ready to use 2 us after the enable signal is set high. */
473         Cy_SysLib_DelayUs(CY_SAR_2US_DELAY);
474 
475         if ((!CY_PASS_V1) && (0UL != (Cy_SAR_flags & CY_SAR_INSTANCE_MASK(base))))
476         {
477             PASS_FIFO_CTRL(base) = PASS_FIFO_V2_CTRL_ENABLED_Msk;
478         }
479     }
480 }
481 
482 
483 /*******************************************************************************
484 * Function Name: Cy_SAR_Disable
485 ****************************************************************************//**
486 *
487 * Turn off the hardware block.
488 *
489 * \param base
490 * Pointer to structure describing registers
491 *
492 * \return None
493 *
494 *******************************************************************************/
Cy_SAR_Disable(SAR_Type * base)495 void Cy_SAR_Disable(SAR_Type *base)
496 {
497     if (_FLD2BOOL(SAR_CTRL_ENABLED, SAR_CTRL(base)))
498     {
499         while (_FLD2BOOL(SAR_STATUS_BUSY, SAR_STATUS(base)))
500         {
501             /* Wait for SAR to go idle */
502         }
503 
504         SAR_CTRL(base) &= ~SAR_CTRL_ENABLED_Msk;
505 
506         if ((!CY_PASS_V1) && (0UL != (Cy_SAR_flags & CY_SAR_INSTANCE_MASK(base))))
507         {
508             PASS_FIFO_CTRL(base) = 0UL;
509         }
510     }
511 }
512 
513 
514 /*******************************************************************************
515 * Function Name: Cy_SAR_DeepSleep
516 ****************************************************************************//**
517 *
518 * This is the preferred routine to prepare the hardware for Deep Sleep.
519 *
520 * It will call \ref Cy_SAR_StopConvert to disable continuous conversions
521 * and wait for SAR conversions to stop before entering Deep Sleep.
522 * If the SARMUX is not configured for Deep Sleep operation, the entire SAR hardware
523 * block will be turned off.
524 *
525 * \param base
526 * Pointer to structure describing registers
527 *
528 * \return None
529 *
530 * \funcusage
531 *
532 * This function is used in the \ref Cy_SAR_DeepSleepCallback. There is no
533 * need to call this function directly.
534 *
535 *******************************************************************************/
Cy_SAR_DeepSleep(SAR_Type * base)536 void Cy_SAR_DeepSleep(SAR_Type *base)
537 {
538     uint32_t ctrlReg = SAR_CTRL(base);
539 
540     enabledBeforeSleep[CY_SAR_INSTANCE(base)].hwEnabled = ctrlReg & SAR_CTRL_ENABLED_Msk;
541 
542     /* Turn off the reference buffer */
543     ctrlReg &= ~SAR_CTRL_REFBUF_EN_Msk;
544 
545     if (SAR_CTRL_ENABLED_Msk == enabledBeforeSleep[CY_SAR_INSTANCE(base)].hwEnabled)
546     {
547 
548         /* Save state of CONTINUOUS bit so that conversions can be re-started upon wake-up */
549         enabledBeforeSleep[CY_SAR_INSTANCE(base)].continuous = SAR_SAMPLE_CTRL(base) & SAR_SAMPLE_CTRL_CONTINUOUS_Msk;
550 
551         Cy_SAR_StopConvert(base);
552 
553         while (_FLD2BOOL(SAR_STATUS_BUSY, SAR_STATUS(base)))
554         {
555             /* Wait for SAR to stop conversions before entering low power */
556         }
557 
558         /* Turn off the entire hardware block only if the SARMUX is not
559          * enabled for Deep Sleep operation. */
560         if (SAR_CTRL_DEEPSLEEP_ON_Msk != (ctrlReg & SAR_CTRL_DEEPSLEEP_ON_Msk))
561         {
562             SAR_CTRL(base) &= ~SAR_CTRL_ENABLED_Msk;
563         }
564     }
565 
566     SAR_CTRL(base) = ctrlReg;
567 }
568 
569 
570 /*******************************************************************************
571 * Function Name: Cy_SAR_Wakeup
572 ****************************************************************************//**
573 *
574 * This is the preferred routine to restore the hardware to the state after calling
575 * \ref Cy_SAR_DeepSleep. Restoring the hardware involves re-enabling the hardware,
576 * the reference buffer, and continuous scanning if it was previously
577 * enabled before entering sleep.
578 *
579 * \param base
580 * Pointer to structure describing registers
581 *
582 * \sideeffect
583 * Calling this function without previously calling \ref Cy_SAR_DeepSleep can lead to
584 * unpredictable results.
585 *
586 * \return None
587 *
588 * \funcusage
589 *
590 * This function is used in the \ref Cy_SAR_DeepSleepCallback. There is no
591 * need to call this function directly.
592 *
593 *******************************************************************************/
Cy_SAR_Wakeup(SAR_Type * base)594 void Cy_SAR_Wakeup(SAR_Type *base)
595 {
596     /* Turn on the reference buffer */
597     SAR_CTRL(base) |= SAR_CTRL_REFBUF_EN_Msk;
598 
599     if (SAR_CTRL_ENABLED_Msk == enabledBeforeSleep[CY_SAR_INSTANCE(base)].hwEnabled)
600     {
601         Cy_SAR_Enable(base);
602 
603         if (SAR_SAMPLE_CTRL_CONTINUOUS_Msk == enabledBeforeSleep[CY_SAR_INSTANCE(base)].continuous)
604         {
605             Cy_SAR_StartConvert(base, CY_SAR_START_CONVERT_CONTINUOUS);
606         }
607     }
608 }
609 
610 
611 /*******************************************************************************
612 * Function Name: Cy_SAR_StartConvert
613 ****************************************************************************//**
614 *
615 * Start a single scan (one shot) of all enabled channels or start scanning
616 * continuously. When in continuous mode, all firmware and hardware triggers
617 * are ignored. To stop continuous scanning, call \ref Cy_SAR_StopConvert.
618 *
619 * \param base
620 * Pointer to structure describing registers
621 *
622 * \param startSelect
623 * A value of the enum \ref cy_en_sar_start_convert_sel_t
624 *
625 * \return None
626 *
627 * \funcusage
628 *
629 * \snippet sar/snippet/main.c SNIPPET_SAR_START_CONVERT
630 *
631 *******************************************************************************/
Cy_SAR_StartConvert(SAR_Type * base,cy_en_sar_start_convert_sel_t startSelect)632 void Cy_SAR_StartConvert(SAR_Type *base, cy_en_sar_start_convert_sel_t startSelect)
633 {
634     CY_ASSERT_L3(CY_SAR_STARTCONVERT(startSelect));
635 
636     switch(startSelect)
637     {
638     case CY_SAR_START_CONVERT_CONTINUOUS:
639         SAR_SAMPLE_CTRL(base) |= SAR_SAMPLE_CTRL_CONTINUOUS_Msk;
640         break;
641     case CY_SAR_START_CONVERT_SINGLE_SHOT:
642     default:
643         SAR_START_CTRL(base) = SAR_START_CTRL_FW_TRIGGER_Msk;
644         break;
645     }
646 }
647 
648 
649 /*******************************************************************************
650 * Function Name: Cy_SAR_StopConvert
651 ****************************************************************************//**
652 *
653 * Stop continuous scanning of enabled channels.
654 * If a conversion is currently executing, that conversion will complete,
655 * but no further conversions will occur until the next call to
656 * \ref Cy_SAR_StartConvert or the next hardware trigger, if enabled.
657 *
658 * \param base
659 * Pointer to structure describing registers
660 *
661 * \return None
662 *
663 * \funcusage
664 *
665 * \snippet sar/snippet/main.c SNIPPET_SAR_STOP_CONVERT
666 *
667 *******************************************************************************/
Cy_SAR_StopConvert(SAR_Type * base)668 void Cy_SAR_StopConvert(SAR_Type *base)
669 {
670     if (SAR_SAMPLE_CTRL_CONTINUOUS_Msk == (SAR_SAMPLE_CTRL(base) & SAR_SAMPLE_CTRL_CONTINUOUS_Msk))
671     {
672         SAR_SAMPLE_CTRL(base) &= ~SAR_SAMPLE_CTRL_CONTINUOUS_Msk;
673     }
674 }
675 
676 
677 /*******************************************************************************
678 * Function Name: Cy_SAR_SetConvertMode
679 ****************************************************************************//**
680 *
681 * Set the mode in which conversions are triggered. This function does
682 * not start any conversions; it only configures the mode for subsequent conversions.
683 *
684 * There are three modes:
685 *   - firmware only; hardware triggering is disabled
686 *   - firmware and edge sensitive hardware triggering
687 *   - firmware and level sensitive hardware triggering
688 *
689 * Note that firmware triggering is always enabled.
690 *
691 * \param base
692 * Pointer to structure describing registers
693 *
694 * \param mode
695 * A value of the enum \ref cy_en_sar_sample_ctrl_trigger_mode_t
696 *
697 * \return None
698 *
699 * \funcusage
700 *
701 * \snippet sar/snippet/main.c SAR_SNIPPET_SET_CONVERT_MODE
702 *
703 *******************************************************************************/
Cy_SAR_SetConvertMode(SAR_Type * base,cy_en_sar_sample_ctrl_trigger_mode_t mode)704 void Cy_SAR_SetConvertMode(SAR_Type *base, cy_en_sar_sample_ctrl_trigger_mode_t mode)
705 {
706     CY_ASSERT_L3(CY_SAR_TRIGGER(mode));
707 
708     /* Clear the TRIGGER_EN and TRIGGER_LEVEL bits */
709     uint32_t sampleCtrlReg = SAR_SAMPLE_CTRL(base) & ~(SAR_SAMPLE_CTRL_DSI_TRIGGER_EN_Msk | SAR_SAMPLE_CTRL_DSI_TRIGGER_LEVEL_Msk);
710 
711     SAR_SAMPLE_CTRL(base) = sampleCtrlReg | (uint32_t)mode;
712 }
713 
714 
715 /*******************************************************************************
716 * Function Name: Cy_SAR_IsEndConversion
717 ****************************************************************************//**
718 *
719 * Immediately return the status of the conversion or does not return (blocking)
720 * until the conversion completes, depending on the retMode parameter.
721 * In blocking mode, there is a time out of about 10 seconds for a CPU speed of
722 * 100 MHz.
723 *
724 * \param base
725 * Pointer to structure describing registers
726 *
727 * \param retMode
728 * A value of the enum \ref cy_en_sar_return_mode_t
729 *
730 * \return
731 * - \ref CY_SAR_SUCCESS : the last conversion is complete
732 * - \ref CY_SAR_CONVERSION_NOT_COMPLETE : the conversion has not completed
733 * - \ref CY_SAR_TIMEOUT : the watchdog timer has expired in blocking mode
734 *
735 * \sideeffect
736 * This function reads the end of conversion status and clears it after.
737 *
738 * \note
739 * \ref CY_SAR_WAIT_FOR_RESULT and \ref CY_SAR_WAIT_FOR_RESULT_INJ return modes are not recommended
740 * for use in RTOS environment.
741 *
742 * \funcusage
743 *
744 * \snippet sar/snippet/main.c SNIPPET_SAR_IS_END_CONVERSION
745 *
746 *******************************************************************************/
Cy_SAR_IsEndConversion(SAR_Type * base,cy_en_sar_return_mode_t retMode)747 cy_en_sar_status_t Cy_SAR_IsEndConversion(SAR_Type *base, cy_en_sar_return_mode_t retMode)
748 {
749     CY_ASSERT_L3(CY_SAR_RETURN(retMode));
750 
751     cy_en_sar_status_t result;
752 
753     uint32_t wdt = 0x1555555UL; /* Watchdog timer for blocking while loop */
754     uint32_t mask = ((CY_SAR_RETURN_STATUS_INJ == retMode) || (CY_SAR_WAIT_FOR_RESULT_INJ == retMode)) ? CY_SAR_INTR_INJ_EOC : CY_SAR_INTR_EOS;
755     uint32_t intr = mask & Cy_SAR_GetInterruptStatus(base);
756 
757     if ((CY_SAR_WAIT_FOR_RESULT == retMode) || (CY_SAR_WAIT_FOR_RESULT_INJ == retMode))
758     {
759         while ((0UL == intr) && (0UL != wdt))
760         {
761             intr = mask & Cy_SAR_GetInterruptStatus(base);
762             wdt--;
763         }
764     }
765 
766     /* Clear the EOS bit */
767     if (mask == intr)
768     {
769         result = CY_SAR_SUCCESS;
770         Cy_SAR_ClearInterrupt(base, mask);
771     }
772     else if (0UL == wdt)
773     {
774         result = CY_SAR_TIMEOUT;
775     }
776     else
777     {
778         result = CY_SAR_CONVERSION_NOT_COMPLETE;
779     }
780 
781     return result;
782 }
783 
784 
785 /*******************************************************************************
786 * Function Name: Cy_SAR_IsChannelSigned
787 ****************************************************************************//**
788 *
789 * Return true if channel result is configured for signed format, else false.
790 * The formats for single-ended and differential channels are independent.
791 * This function will first check whether the channel is single-ended or differential.
792 *
793 * \param base
794 * Pointer to structure describing registers
795 *
796 * \param chan
797 * The channel to check, between 0 and \ref CY_SAR_INJ_CHANNEL
798 *
799 * \return
800 * If channel number is invalid, false is returned
801 *
802 * \funcusage
803 *
804 * \snippet sar/snippet/main.c SNIPPET_SAR_IS_CHANNEL_SIGNED
805 *
806 *******************************************************************************/
Cy_SAR_IsChannelSigned(const SAR_Type * base,uint32_t chan)807 bool Cy_SAR_IsChannelSigned(const SAR_Type *base, uint32_t chan)
808 {
809     CY_ASSERT_L2(CHAN_NUM(chan));
810 
811     bool isSigned = false;
812 
813     if (chan < CY_SAR_NUM_CHANNELS)
814     {
815         /* Sign bits are stored separately for differential and single ended channels. */
816         if (true == Cy_SAR_IsChannelDifferential(base, chan))
817         { /* Differential channel */
818             if (SAR_SAMPLE_CTRL_DIFFERENTIAL_SIGNED_Msk == (SAR_SAMPLE_CTRL(base) & SAR_SAMPLE_CTRL_DIFFERENTIAL_SIGNED_Msk))
819             {
820                 isSigned = true;
821             }
822         }
823         else
824         { /* Single ended channel */
825             if (SAR_SAMPLE_CTRL_SINGLE_ENDED_SIGNED_Msk == (SAR_SAMPLE_CTRL(base) & SAR_SAMPLE_CTRL_SINGLE_ENDED_SIGNED_Msk))
826             {
827                 isSigned = true;
828             }
829         }
830     }
831 
832     return isSigned;
833 }
834 
835 
836 /*******************************************************************************
837 * Function Name: Cy_SAR_IsChannelSingleEnded
838 ****************************************************************************//**
839 *
840 * Return true if channel is single ended, else false
841 *
842 * \param base
843 * Pointer to structure describing registers
844 *
845 * \param chan
846 * The channel to check, between 0 and \ref CY_SAR_INJ_CHANNEL
847 *
848 * \return
849 * If channel number is invalid, false is returned
850 *
851 * \funcusage
852 *
853 * \snippet sar/snippet/main.c SNIPPET_SAR_IS_CHANNEL_SE
854 *
855 *******************************************************************************/
Cy_SAR_IsChannelSingleEnded(const SAR_Type * base,uint32_t chan)856 bool Cy_SAR_IsChannelSingleEnded(const SAR_Type *base, uint32_t chan)
857 {
858     CY_ASSERT_L2(CHAN_NUM(chan));
859 
860     bool isSingleEnded = false;
861 
862     if (chan < CY_SAR_SEQ_NUM_CHANNELS)
863     {
864         if (0UL == (SAR_CHAN_CONFIG(base, chan) & (SAR_CHAN_CONFIG_DIFFERENTIAL_EN_Msk | SAR_CHAN_CONFIG_NEG_ADDR_EN_Msk)))
865         {
866             isSingleEnded = true;
867         }
868     }
869     else if (CY_SAR_INJ_CHANNEL == chan)
870     {
871         isSingleEnded = !_FLD2BOOL(SAR_INJ_CHAN_CONFIG_INJ_DIFFERENTIAL_EN, SAR_INJ_CHAN_CONFIG(base));
872     }
873     else
874     {
875         /* Return false */
876     }
877 
878     return isSingleEnded;
879 }
880 
881 
882 /*******************************************************************************
883 * Function Name: Cy_SAR_GetResult16
884 ****************************************************************************//**
885 *
886 * Return the data available in the channel result data register as a signed
887 * 16-bit integer.
888 *
889 * \param base
890 * Pointer to structure describing registers
891 *
892 * \param chan
893 * The channel to read the result from, between 0 and \ref CY_SAR_INJ_CHANNEL
894 *
895 * \return
896 * Data is returned as a signed 16-bit integer.
897 * If channel number is invalid, 0 is returned.
898 *
899 * \funcusage
900 *
901 * \snippet sar/snippet/main.c SNIPPET_SAR_GET_RESULT16
902 *
903 *******************************************************************************/
Cy_SAR_GetResult16(const SAR_Type * base,uint32_t chan)904 int16_t Cy_SAR_GetResult16(const SAR_Type *base, uint32_t chan)
905 {
906     CY_ASSERT_L2(CHAN_NUM(chan));
907 
908     uint32_t adcResult = 0UL;
909 
910     if (chan < CY_SAR_SEQ_NUM_CHANNELS)
911     {
912         adcResult = _FLD2VAL(SAR_CHAN_RESULT_RESULT, SAR_CHAN_RESULT(base, chan));
913     }
914     else if (CY_SAR_INJ_CHANNEL == chan)
915     {
916         adcResult = _FLD2VAL(SAR_INJ_RESULT_INJ_RESULT, SAR_INJ_RESULT(base));
917     }
918     else
919     {
920         /* Return zero */
921     }
922 
923     return (int16_t) adcResult;
924 }
925 
926 
927 /*******************************************************************************
928 * Function Name: Cy_SAR_GetResult32
929 ****************************************************************************//**
930 *
931 * Return the data available in the channel result data register as a signed
932 * 32-bit integer.
933 *
934 * \param base
935 * Pointer to structure describing registers
936 *
937 * \param chan
938 * The channel to read the result from, between 0 and \ref CY_SAR_INJ_CHANNEL
939 *
940 * \return
941 * Data is returned as a signed 32-bit integer.
942 * If channel number is invalid, 0 is returned.
943 *
944 * \funcusage
945 *
946 * \snippet sar/snippet/main.c SNIPPET_SAR_GET_RESULT32
947 *
948 *******************************************************************************/
Cy_SAR_GetResult32(const SAR_Type * base,uint32_t chan)949 int32_t Cy_SAR_GetResult32(const SAR_Type *base, uint32_t chan)
950 {
951     return ((int32_t)Cy_SAR_GetResult16(base, chan));
952 }
953 
954 
955 /*******************************************************************************
956 * Function Name: Cy_SAR_SetLowLimit
957 ****************************************************************************//**
958 *
959 * Set the low threshold for range detection. The values are interpreted
960 * as signed or unsigned according to the channel configuration. Range
961 * detection is done on the value stored in the result register. That is, after
962 * averaging, shifting sign extension, and left/right alignment.
963 *
964 * \param base
965 * Pointer to structure describing registers
966 *
967 * \param lowLimit
968 * The low threshold for range detection
969 *
970 * \return None
971 *
972 * \funcusage
973 *
974 * \snippet sar/snippet/main.c SNIPPET_SAR_SET_LOWHIGH_LIMIT
975 *
976 *******************************************************************************/
Cy_SAR_SetLowLimit(SAR_Type * base,uint32_t lowLimit)977 void Cy_SAR_SetLowLimit(SAR_Type *base, uint32_t lowLimit)
978 {
979     CY_ASSERT_L2(CY_SAR_RANGE_LIMIT(lowLimit));
980 
981     CY_REG32_CLR_SET(SAR_RANGE_THRES(base), SAR_RANGE_THRES_RANGE_LOW, lowLimit);
982 }
983 
984 
985 /*******************************************************************************
986 * Function Name: Cy_SAR_SetHighLimit
987 ****************************************************************************//**
988 *
989 * Set the high threshold for range detection. The values are interpreted
990 * as signed or unsigned according to the channel configuration. Range
991 * detection is done on the value stored in the result register. That is, after
992 * averaging, shifting sign extension, and left/right alignment.
993 *
994 * \param base
995 * Pointer to structure describing registers
996 *
997 * \param highLimit
998 * The high threshold for range detection
999 *
1000 * \return None
1001 *
1002 * \funcusage
1003 *
1004 * \snippet sar/snippet/main.c SNIPPET_SAR_SET_LOWHIGH_LIMIT
1005 *
1006 *******************************************************************************/
Cy_SAR_SetHighLimit(SAR_Type * base,uint32_t highLimit)1007 void Cy_SAR_SetHighLimit(SAR_Type *base, uint32_t highLimit)
1008 {
1009     CY_ASSERT_L2(CY_SAR_RANGE_LIMIT(highLimit));
1010 
1011     CY_REG32_CLR_SET(SAR_RANGE_THRES(base), SAR_RANGE_THRES_RANGE_HIGH, highLimit);
1012 }
1013 
1014 
1015 /*******************************************************************************
1016 * Function Name: Cy_SAR_SetChannelOffset
1017 ****************************************************************************//**
1018 *
1019 * Store the channel offset for the voltage conversion functions.
1020 *
1021 * Offset is applied to counts before unit scaling and gain.
1022 * See \ref Cy_SAR_CountsTo_Volts for more about this formula.
1023 *
1024 * To change channel 0's offset based on a known V_offset_mV, use:
1025 *
1026 *     Cy_SAR_SetOffset(0UL, -1 * V_offset_mV * (1UL << Resolution) / (2 * V_ref_mV));
1027 *
1028 * \param base
1029 * Pointer to structure describing registers
1030 *
1031 * \param chan
1032 * The channel number, between 0 and \ref CY_SAR_INJ_CHANNEL.
1033 *
1034 * \param offset
1035 * The count value measured when the inputs are shorted or
1036 * connected to the same input voltage.
1037 *
1038 * \return
1039 * - \ref CY_SAR_SUCCESS : offset was set successfully
1040 * - \ref CY_SAR_BAD_PARAM : channel number is equal to or greater than \ref CY_SAR_NUM_CHANNELS
1041 *
1042 *******************************************************************************/
Cy_SAR_SetChannelOffset(const SAR_Type * base,uint32_t chan,int16_t offset)1043 cy_en_sar_status_t Cy_SAR_SetChannelOffset(const SAR_Type *base, uint32_t chan, int16_t offset)
1044 {
1045     CY_ASSERT_L2(CHAN_NUM(chan));
1046 
1047     cy_en_sar_status_t result = CY_SAR_BAD_PARAM;
1048 
1049     if (chan < CY_SAR_NUM_CHANNELS)
1050     {
1051         Cy_SAR_offset[chan][CY_SAR_INSTANCE(base)] = offset;
1052         result = CY_SAR_SUCCESS;
1053     }
1054 
1055     return result;
1056 }
1057 
1058 
1059 /*******************************************************************************
1060 * Function Name: Cy_SAR_SetChannelGain
1061 ****************************************************************************//**
1062 *
1063 * Store the gain value for the voltage conversion functions.
1064 * The gain is configured at initialization in \ref Cy_SAR_Init
1065 * based on the SARADC resolution and voltage reference.
1066 *
1067 * Gain is applied after offset and unit scaling.
1068 * See \ref Cy_SAR_CountsTo_Volts for more about this formula.
1069 *
1070 * To change channel 0's gain based on a known V_ref_mV, use:
1071 *
1072 *     Cy_SAR_SetGain(0UL, 10000 * (1UL << Resolution) / (2 * V_ref_mV));
1073 *
1074 * \param base
1075 * Pointer to structure describing registers
1076 *
1077 * \param chan
1078 * The channel number, between 0 and \ref CY_SAR_INJ_CHANNEL.
1079 *
1080 * \param adcGain
1081 * The gain in counts per 10 volt.
1082 *
1083 * \return
1084 * - \ref CY_SAR_SUCCESS : gain was set successfully
1085 * - \ref CY_SAR_BAD_PARAM : channel number is equal to or greater than \ref CY_SAR_NUM_CHANNELS
1086 *
1087 *******************************************************************************/
Cy_SAR_SetChannelGain(const SAR_Type * base,uint32_t chan,int32_t adcGain)1088 cy_en_sar_status_t Cy_SAR_SetChannelGain(const SAR_Type *base, uint32_t chan, int32_t adcGain)
1089 {
1090     CY_ASSERT_L2(CHAN_NUM(chan));
1091 
1092     cy_en_sar_status_t result = CY_SAR_BAD_PARAM;
1093 
1094     if (chan < CY_SAR_NUM_CHANNELS)
1095     {
1096         Cy_SAR_countsPer10Volt[chan][CY_SAR_INSTANCE(base)] = adcGain;
1097         result = CY_SAR_SUCCESS;
1098     }
1099 
1100     return result;
1101 }
1102 
1103 
1104 /*******************************************************************************
1105 * Function Name: Cy_SAR_RawCounts2Counts
1106 ****************************************************************************//**
1107 *
1108 * Convert the channel result to a consistent result after accounting for
1109 * averaging and subtracting the offset.
1110 * The equation used is:
1111 *
1112 *     Counts = (RawCounts/AvgDivider - Offset)
1113 *
1114 * where,
1115 * - RawCounts: Raw counts from SAR 16-bit CHAN_RESULT register
1116 * - AvgDivider: divider based on averaging mode (\ref cy_en_sar_sample_ctrl_avg_mode_t) and number of samples averaged
1117 *   (\ref cy_en_sar_sample_ctrl_avg_cnt_t)
1118 *   - \ref CY_SAR_AVG_MODE_SEQUENTIAL_ACCUM : AvgDivider is the number of samples averaged or 16, whichever is smaller
1119 *   - \ref CY_SAR_AVG_MODE_SEQUENTIAL_FIXED : AvgDivider is 1
1120 *   - \ref CY_SAR_AVG_MODE_INTERLEAVED : AvgDivider is the number of samples averaged
1121 * - Offset: Value stored by the \ref Cy_SAR_SetChannelOffset function.
1122 *
1123 * \param base
1124 * Pointer to structure describing registers
1125 *
1126 * \param chan
1127 * The channel number, between 0 and \ref CY_SAR_INJ_CHANNEL
1128 *
1129 * \param adcCounts
1130 * Conversion result from \ref Cy_SAR_GetResult16
1131 *
1132 * \return
1133 * adcCounts after averaging and offset adjustments.
1134 * If channel number is invalid, adcCounts is returned unmodified.
1135 *
1136 * \funcusage
1137 *
1138 * This function is used by \ref Cy_SAR_CountsTo_Volts, \ref Cy_SAR_CountsTo_mVolts,
1139 * and \ref Cy_SAR_CountsTo_uVolts. Calling this function directly is usually
1140 * not needed.
1141 *
1142 *******************************************************************************/
Cy_SAR_RawCounts2Counts(const SAR_Type * base,uint32_t chan,int16_t adcCounts)1143 int16_t Cy_SAR_RawCounts2Counts(const SAR_Type *base, uint32_t chan, int16_t adcCounts)
1144 {
1145     int16_t retVal = adcCounts;
1146 
1147     CY_ASSERT_L2(CHAN_NUM(chan));
1148 
1149     if (chan < CY_SAR_NUM_CHANNELS)
1150     {
1151         /* Divide the adcCount when accumulate averaging mode selected */
1152         if (!_FLD2BOOL(SAR_SAMPLE_CTRL_AVG_SHIFT, SAR_SAMPLE_CTRL(base)))
1153         { /* If Average mode != fixed */
1154             if (((chan < CY_SAR_SEQ_NUM_CHANNELS) && _FLD2BOOL(SAR_CHAN_CONFIG_AVG_EN,         SAR_CHAN_CONFIG(base, chan))) ||
1155                 ((chan == CY_SAR_INJ_CHANNEL)     && _FLD2BOOL(SAR_INJ_CHAN_CONFIG_INJ_AVG_EN, SAR_INJ_CHAN_CONFIG(base))))
1156             { /* If channel uses averaging */
1157                 uint32_t averageAdcSamplesDiv;
1158 
1159                 /* Divide by 2^(AVG_CNT + 1) */
1160                 averageAdcSamplesDiv = (SAR_SAMPLE_CTRL(base) & SAR_SAMPLE_CTRL_AVG_CNT_Msk) >> SAR_SAMPLE_CTRL_AVG_CNT_Pos;
1161                 averageAdcSamplesDiv = (1UL << (averageAdcSamplesDiv + 1UL));
1162 
1163                 /* If averaging mode is ACCUNDUMP (channel will be sampled back to back and averaged)
1164                 * divider limit is 16 */
1165                 if (SAR_SAMPLE_CTRL_AVG_MODE_Msk != (SAR_SAMPLE_CTRL(base) & SAR_SAMPLE_CTRL_AVG_MODE_Msk))
1166                 {
1167                     if (averageAdcSamplesDiv > 16UL)
1168                     {
1169                         averageAdcSamplesDiv = 16UL;
1170                     }
1171                 }
1172 
1173                 /* If unsigned format, prevent sign extension */
1174                 if (false == Cy_SAR_IsChannelSigned(base, chan))
1175                 {
1176                     retVal = (int16_t)(uint32_t)((uint16_t) retVal / averageAdcSamplesDiv);
1177                 }
1178                 else
1179                 {
1180                     retVal /= (int16_t) averageAdcSamplesDiv;
1181                 }
1182             }
1183         }
1184 
1185         /* Subtract ADC offset */
1186         retVal -= Cy_SAR_offset[chan][CY_SAR_INSTANCE(base)];
1187     }
1188 
1189     return (retVal);
1190 }
1191 
1192 
1193 /*******************************************************************************
1194 * Function Name: Cy_SAR_CountsTo_Volts
1195 ****************************************************************************//**
1196 *
1197 * Convert the ADC output to Volts as a float32. For example, if the ADC
1198 * measured 0.534 volts, the return value would be 0.534.
1199 * The calculation of voltage depends on the channel offset, gain and other parameters.
1200 * The equation used is:
1201 *
1202 *     V = (RawCounts/AvgDivider - Offset)*TEN_VOLT/Gain
1203 *
1204 * where,
1205 * - RawCounts: Raw counts from SAR 16-bit CHAN_RESULT register
1206 * - AvgDivider: divider based on averaging mode (\ref cy_en_sar_sample_ctrl_avg_mode_t) and number of samples averaged
1207 *   (\ref cy_en_sar_sample_ctrl_avg_cnt_t)
1208 *   - \ref CY_SAR_AVG_MODE_SEQUENTIAL_ACCUM : AvgDivider is the number of samples averaged or 16, whichever is smaller
1209 *   - \ref CY_SAR_AVG_MODE_SEQUENTIAL_FIXED : AvgDivider is 1
1210 *   - \ref CY_SAR_AVG_MODE_INTERLEAVED : AvgDivider is the number of samples averaged
1211 * - Offset: Value stored by the \ref Cy_SAR_SetChannelOffset function.
1212 * - TEN_VOLT: 10 V constant since the gain is in counts per 10 volts.
1213 * - Gain: Value stored by the \ref Cy_SAR_SetChannelGain function.
1214 *
1215 * \note
1216 * This function is only valid when result alignment is right aligned.
1217 *
1218 * \param base
1219 * Pointer to structure describing registers
1220 *
1221 * \param chan
1222 * The channel number, between 0 and \ref CY_SAR_INJ_CHANNEL
1223 *
1224 * \param adcCounts
1225 * Conversion result from \ref Cy_SAR_GetResult16
1226 *
1227 * \return
1228 * Result in Volts.
1229 * - If channel number is invalid, 0 is returned.
1230 * - If channel is left aligned, 0 is returned.
1231 *
1232 * \funcusage
1233 *
1234 * \snippet sar/snippet/main.c SNIPPET_SAR_COUNTSTO_VOLTS
1235 *
1236 *******************************************************************************/
Cy_SAR_CountsTo_Volts(const SAR_Type * base,uint32_t chan,int16_t adcCounts)1237 float32_t Cy_SAR_CountsTo_Volts(const SAR_Type *base, uint32_t chan, int16_t adcCounts)
1238 {
1239     CY_ASSERT_L2(CHAN_NUM(chan));
1240 
1241     float32_t result_Volts = 0.0f;
1242 
1243     if (chan < CY_SAR_NUM_CHANNELS)
1244     {
1245         if (IS_RIGHT_ALIGN)
1246         {
1247             result_Volts = (float32_t)Cy_SAR_RawCounts2Counts(base, chan, adcCounts) * CY_SAR_10V_COUNTS;
1248             result_Volts /= (float32_t)Cy_SAR_countsPer10Volt[chan][CY_SAR_INSTANCE(base)];
1249         }
1250     }
1251 
1252     return result_Volts;
1253 }
1254 
1255 
1256 /*******************************************************************************
1257 * Function Name: Cy_SAR_CountsTo_mVolts
1258 ****************************************************************************//**
1259 *
1260 * Convert the ADC output to millivolts as an int16. For example, if the ADC
1261 * measured 0.534 volts, the return value would be 534.
1262 * The calculation of voltage depends on the channel offset, gain and other parameters.
1263 * The equation used is:
1264 *
1265 *     V = (RawCounts/AvgDivider - Offset)*TEN_VOLT/Gain
1266 *     mV = V * 1000
1267 *
1268 * where,
1269 * - RawCounts: Raw counts from SAR 16-bit CHAN_RESULT register
1270 * - AvgDivider: divider based on averaging mode (\ref cy_en_sar_sample_ctrl_avg_mode_t) and number of samples averaged
1271 *   (\ref cy_en_sar_sample_ctrl_avg_cnt_t)
1272 *   - \ref CY_SAR_AVG_MODE_SEQUENTIAL_ACCUM : AvgDivider is the number of samples averaged or 16, whichever is smaller
1273 *   - \ref CY_SAR_AVG_MODE_SEQUENTIAL_FIXED : AvgDivider is 1
1274 *   - \ref CY_SAR_AVG_MODE_INTERLEAVED : AvgDivider is the number of samples averaged
1275 * - Offset: Value stored by the \ref Cy_SAR_SetChannelOffset function.
1276 * - TEN_VOLT: 10 V constant since the gain is in counts per 10 volts.
1277 * - Gain: Value stored by the \ref Cy_SAR_SetChannelGain function.
1278 *
1279 * \note
1280 * This function is only valid when result alignment is right aligned.
1281 *
1282 * \param base
1283 * Pointer to structure describing registers
1284 *
1285 * \param chan
1286 * The channel number, between 0 and \ref CY_SAR_INJ_CHANNEL
1287 *
1288 * \param adcCounts
1289 * Conversion result from \ref Cy_SAR_GetResult16
1290 *
1291 * \return
1292 * Result in millivolts.
1293 * - If channel number is invalid, 0 is returned.
1294 * - If channel is left aligned, 0 is returned.
1295 *
1296 * \funcusage
1297 *
1298 * \snippet sar/snippet/main.c SNIPPET_SAR_COUNTSTO_MVOLTS
1299 *
1300 *******************************************************************************/
Cy_SAR_CountsTo_mVolts(const SAR_Type * base,uint32_t chan,int16_t adcCounts)1301 int16_t Cy_SAR_CountsTo_mVolts(const SAR_Type *base, uint32_t chan, int16_t adcCounts)
1302 {
1303     CY_ASSERT_L2(CHAN_NUM(chan));
1304 
1305     int32_t result_mVolts = 0;
1306 
1307     if (chan < CY_SAR_NUM_CHANNELS)
1308     {
1309         if (IS_RIGHT_ALIGN)
1310         {
1311             int16_t locCounts = Cy_SAR_RawCounts2Counts(base, chan, adcCounts);
1312 
1313             result_mVolts = ((int32_t)locCounts * CY_SAR_10MV_COUNTS);
1314             if (locCounts > 0)
1315             {
1316                 result_mVolts += Cy_SAR_countsPer10Volt[chan][CY_SAR_INSTANCE(base)] / 2;
1317             }
1318             else
1319             {
1320                 result_mVolts -= Cy_SAR_countsPer10Volt[chan][CY_SAR_INSTANCE(base)] / 2;
1321             }
1322             result_mVolts /= Cy_SAR_countsPer10Volt[chan][CY_SAR_INSTANCE(base)];
1323         }
1324     }
1325 
1326     return (int16_t) result_mVolts;
1327 }
1328 
1329 
1330 /*******************************************************************************
1331 * Function Name: Cy_SAR_CountsTo_uVolts
1332 ****************************************************************************//**
1333 *
1334 * Convert the ADC output to microvolts as a int32. For example, if the ADC
1335 * measured 0.534 volts, the return value would be 534000.
1336 * The calculation of voltage depends on the channel offset, gain and other parameters.
1337 * The equation used is:
1338 *
1339 *     V = (RawCounts/AvgDivider - Offset)*TEN_VOLT/Gain
1340 *     uV = V * 1000000
1341 *
1342 * where,
1343 * - RawCounts: Raw counts from SAR 16-bit CHAN_RESULT register
1344 * - AvgDivider: divider based on averaging mode (\ref cy_en_sar_sample_ctrl_avg_mode_t) and number of samples averaged
1345 *   (\ref cy_en_sar_sample_ctrl_avg_cnt_t)
1346 *   - \ref CY_SAR_AVG_MODE_SEQUENTIAL_ACCUM : AvgDivider is the number of samples averaged or 16, whichever is smaller
1347 *   - \ref CY_SAR_AVG_MODE_SEQUENTIAL_FIXED : AvgDivider is 1
1348 *   - \ref CY_SAR_AVG_MODE_INTERLEAVED : AvgDivider is the number of samples averaged
1349 * - Offset: Value stored by the \ref Cy_SAR_SetChannelOffset function.
1350 * - TEN_VOLT: 10 V constant since the gain is in counts per 10 volts.
1351 * - Gain: Value stored by the \ref Cy_SAR_SetChannelGain function.
1352 *
1353 * \note
1354 * This function is only valid when result alignment is right aligned.
1355 *
1356 * \param base
1357 * Pointer to structure describing registers
1358 *
1359 * \param chan
1360 * The channel number, between 0 and \ref CY_SAR_INJ_CHANNEL
1361 *
1362 * \param adcCounts
1363 * Conversion result from \ref Cy_SAR_GetResult16
1364 *
1365 * \return
1366 * Result in microvolts.
1367 * - If channel number is valid, 0 is returned.
1368 * - If channel is left aligned, 0 is returned.
1369 *
1370 * \funcusage
1371 *
1372 * \snippet sar/snippet/main.c SNIPPET_SAR_COUNTSTO_UVOLTS
1373 *
1374 *******************************************************************************/
Cy_SAR_CountsTo_uVolts(const SAR_Type * base,uint32_t chan,int16_t adcCounts)1375 int32_t Cy_SAR_CountsTo_uVolts(const SAR_Type *base, uint32_t chan, int16_t adcCounts)
1376 {
1377     CY_ASSERT_L2(CHAN_NUM(chan));
1378 
1379     int64_t result_uVolts = 0;
1380 
1381     if (chan < CY_SAR_NUM_CHANNELS)
1382     {
1383         if (IS_RIGHT_ALIGN)
1384         {
1385             result_uVolts = (int64_t)Cy_SAR_RawCounts2Counts(base, chan, adcCounts) * CY_SAR_10UV_COUNTS;
1386             result_uVolts /= Cy_SAR_countsPer10Volt[chan][CY_SAR_INSTANCE(base)];
1387         }
1388     }
1389 
1390     return ((int32_t)result_uVolts);
1391 }
1392 
1393 
1394 /*******************************************************************************
1395 * Function Name: Cy_SAR_SetAnalogSwitch
1396 ****************************************************************************//**
1397 *
1398 * Provide firmware control of the SARMUX switches for firmware sequencing.
1399 * Each call to this function can open or close a set of switches.
1400 * Previously configured switches are untouched.
1401 *
1402 * If the SARSEQ is enabled, there is no need to use this function.
1403 *
1404 * \param base
1405 * Pointer to structure describing registers
1406 *
1407 * \param switchSelect
1408 * The switch register that contains the desired switches. Select a value
1409 * from \ref cy_en_sar_switch_register_sel_t.
1410 *
1411 * \param switchMask
1412 * The mask of the switches to either open or close.
1413 * Select one or more values from the \ref cy_en_sar_mux_switch_fw_ctrl_t enum
1414 * and "OR" them together.
1415 *
1416 * \param state
1417 * Open or close the desired switches. Select a value from \ref cy_en_sar_switch_state_t.
1418 *
1419 * \return None
1420 *
1421 * \funcusage
1422 *
1423 * \snippet sar/snippet/main.c SAR_SNIPPET_SET_ANALOG_SWITCH
1424 *
1425 *******************************************************************************/
Cy_SAR_SetAnalogSwitch(SAR_Type * base,cy_en_sar_switch_register_sel_t switchSelect,uint32_t switchMask,cy_en_sar_switch_state_t state)1426 void Cy_SAR_SetAnalogSwitch(SAR_Type *base, cy_en_sar_switch_register_sel_t switchSelect, uint32_t switchMask, cy_en_sar_switch_state_t state)
1427 {
1428     CY_ASSERT_L3(CY_SAR_SWITCHSELECT(switchSelect));
1429     CY_ASSERT_L2(CY_SAR_SWITCHMASK(switchMask));
1430     CY_ASSERT_L3(CY_SAR_SWITCHSTATE(state));
1431     (void)switchSelect; /* Suppress warning */
1432 
1433     __IOM uint32_t *switchReg;
1434     __IOM uint32_t *switchClearReg;
1435 
1436     switchReg = &SAR_MUX_SWITCH0(base);
1437     switchClearReg = &SAR_MUX_SWITCH_CLEAR0(base);
1438 
1439     switch(state)
1440     {
1441     case CY_SAR_SWITCH_CLOSE:
1442         *switchReg |= switchMask;
1443         break;
1444     case CY_SAR_SWITCH_OPEN:
1445     default:
1446 
1447         /* Unlike the close case, we are not OR'ing the register. Set 1 to clear.*/
1448         *switchClearReg = switchMask;
1449         break;
1450     }
1451 }
1452 
1453 
1454 /*******************************************************************************
1455 * Function Name: Cy_SAR_GetAnalogSwitch
1456 ****************************************************************************//**
1457 *
1458 * Return the state (open or close) of SARMUX switches.
1459 *
1460 * \param base
1461 * Pointer to structure describing registers
1462 *
1463 * \param switchSelect
1464 * The switch register that contains the desired switches. Select a value
1465 * from \ref cy_en_sar_switch_register_sel_t.
1466 *
1467 * \return
1468 * Each bit corresponds to a single switch, where a bit value of 0 is open
1469 * and 1 is closed.
1470 * Compare this value to the switch masks in \ref cy_en_sar_mux_switch_fw_ctrl_t.
1471 *
1472 *******************************************************************************/
Cy_SAR_GetAnalogSwitch(const SAR_Type * base,cy_en_sar_switch_register_sel_t switchSelect)1473 uint32_t Cy_SAR_GetAnalogSwitch(const SAR_Type *base, cy_en_sar_switch_register_sel_t switchSelect)
1474 {
1475     CY_ASSERT_L3(CY_SAR_SWITCHSELECT(switchSelect));
1476     (void)switchSelect; /* Suppress warning */
1477     return SAR_MUX_SWITCH0(base);
1478 }
1479 
1480 
1481 /*******************************************************************************
1482 * Function Name: Cy_SAR_SetSwitchSarSeqCtrl
1483 ****************************************************************************//**
1484 *
1485 * Enable or disable SARSEQ control of one or more switches.
1486 * Previously configured switches are untouched.
1487 *
1488 * \param base
1489 * Pointer to structure describing registers
1490 *
1491 * \param switchMask
1492 * The mask of the switches.
1493 * Select one or more values from the \ref cy_en_sar_mux_switch_sq_ctrl_t enum
1494 * and "OR" them together.
1495 *
1496 * \param ctrl
1497 * Enable or disable SARSEQ control. Select a value from \ref cy_en_sar_switch_sar_seq_ctrl_t.
1498 *
1499 * \return None
1500 *
1501 * \funcusage
1502 *
1503 * \snippet sar/snippet/main.c SAR_SNIPPET_SET_SWITCH_SAR_SEQ_CTRL
1504 *
1505 *******************************************************************************/
Cy_SAR_SetSwitchSarSeqCtrl(SAR_Type * base,uint32_t switchMask,cy_en_sar_switch_sar_seq_ctrl_t ctrl)1506 void Cy_SAR_SetSwitchSarSeqCtrl(SAR_Type *base, uint32_t switchMask, cy_en_sar_switch_sar_seq_ctrl_t ctrl)
1507 {
1508     CY_ASSERT_L2(CY_SAR_SQMASK(switchMask));
1509     CY_ASSERT_L3(CY_SAR_SQCTRL(ctrl));
1510 
1511     switch(ctrl)
1512     {
1513     case CY_SAR_SWITCH_SEQ_CTRL_ENABLE:
1514         SAR_MUX_SWITCH_SQ_CTRL(base) |= switchMask;
1515         break;
1516     case CY_SAR_SWITCH_SEQ_CTRL_DISABLE:
1517     default:
1518         SAR_MUX_SWITCH_SQ_CTRL(base) &= ~switchMask;
1519         break;
1520     }
1521 }
1522 
1523 
1524 /*******************************************************************************
1525 * Function Name: Cy_SAR_DeepSleepCallback
1526 ****************************************************************************//**
1527 *
1528 * Callback to prepare the SAR before entering Deep Sleep
1529 * and to re-enable the SAR after exiting Deep Sleep.
1530 *
1531 * \param callbackParams
1532 * Pointer to structure of type \ref cy_stc_syspm_callback_params_t
1533 *
1534 * \param mode
1535 * Callback mode, see \ref cy_en_syspm_callback_mode_t
1536 *
1537 * \return
1538 * See \ref cy_en_syspm_status_t
1539 *
1540 * \funcusage
1541 *
1542 * \snippet sar/snippet/main.c SNIPPET_SAR_DEEPSLEEP_CALLBACK
1543 *
1544 *******************************************************************************/
Cy_SAR_DeepSleepCallback(const cy_stc_syspm_callback_params_t * callbackParams,cy_en_syspm_callback_mode_t mode)1545 cy_en_syspm_status_t Cy_SAR_DeepSleepCallback(const cy_stc_syspm_callback_params_t *callbackParams, cy_en_syspm_callback_mode_t mode)
1546 {
1547     cy_en_syspm_status_t returnValue = CY_SYSPM_SUCCESS;
1548 
1549     if (CY_PASS_V1)
1550     {
1551         if (CY_SYSPM_BEFORE_TRANSITION == mode)
1552         { /* Actions that should be done before entering the Deep Sleep mode */
1553             Cy_SAR_DeepSleep((SAR_Type *)callbackParams->base);
1554         }
1555         else if (CY_SYSPM_AFTER_TRANSITION == mode)
1556         { /* Actions that should be done after exiting the Deep Sleep mode */
1557             Cy_SAR_Wakeup((SAR_Type *)callbackParams->base);
1558         }
1559         else
1560         { /* Does nothing in other modes */
1561         }
1562     }
1563 
1564     return returnValue;
1565 }
1566 
1567 
1568 /*******************************************************************************
1569 * Function Name: Cy_SAR_ScanCountEnable
1570 ****************************************************************************//**
1571 *
1572 * Enables the Scanning Counter.
1573 * Suitable for PASS_V2.
1574 *
1575 * \param base
1576 * Pointer to the structure of SAR instance registers.
1577 *
1578 * \return The status:
1579 * - CY_SAR_BAD_PARAM - either the feature is not supported by this IP version or
1580 *                      the injection channel is triggered and not tailgating.
1581 * - CY_SAR_SUCCESS - the SAR Scanning Counter feature is successfully enabled.
1582 *
1583 * \funcusage \snippet sar/snippet/main.c SNIPPET_SAR_DS
1584 *
1585 *******************************************************************************/
Cy_SAR_ScanCountEnable(const SAR_Type * base)1586 cy_en_sar_status_t Cy_SAR_ScanCountEnable(const SAR_Type * base)
1587 {
1588     cy_en_sar_status_t retVal = CY_SAR_BAD_PARAM;
1589 
1590     if (!CY_PASS_V1)
1591     {
1592         uint32_t interruptState = Cy_SysLib_EnterCriticalSection();
1593         uint32_t locInjChanCfg = SAR_INJ_CHAN_CONFIG(base);
1594         /* If the injection channel is triggered the Scan Counter could be enabled only if the injection channel configured as tailgating  */
1595         if ((0UL != (locInjChanCfg & SAR_V2_INJ_CHAN_CONFIG_INJ_START_EN_Msk)) ? (0UL == (locInjChanCfg & SAR_V2_INJ_CHAN_CONFIG_INJ_TAILGATING_Msk)) : true)
1596         {
1597             PASS_SAR_OVR_CTRL(CY_PASS_V2_ADDR) |= CY_SAR_INSTANCE_MASK(base) << PASS_V2_SAR_OVR_CTRL_TR_SCAN_CNT_SEL_Pos;
1598             Cy_SysLib_ExitCriticalSection(interruptState);
1599             retVal = CY_SAR_SUCCESS;
1600         }
1601     }
1602 
1603     return (retVal);
1604 }
1605 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 11.3')
1606 
1607 
1608 #if defined(__cplusplus)
1609 }
1610 #endif
1611 
1612 #endif /* CY_IP_MXS40PASS_SAR */
1613 
1614 /* [] END OF FILE */
1615