AN219755 Using a SAR ADC in TRAVEO™ T2G automotive microcontrollers
About this document
Scope and purpose
This application note demonstrates how to configure and use a SAR ADC in TRAVEO™ T2G automotive microcontrollers with a software trigger, a hardware trigger, group processing, averaging, range detection, pulse detection, diagnosis, and calibration.
Intended audience
This document is intended for anyone who uses the SAR ADC of the TRAVEO™ T2G automotive microcontrollers.
Associated part family
TRAVEO™ T2G family
Introduction
This application note describes how to use a SAR ADC for Infineon TRAVEO™ T2G automotive microcontrollers. The SAR ADC converts analog input voltages into digital values. The analog channels can be an individual or grouped. Each channel can be triggered by software or hardware. The SAR ADC features averaging, range detection, pulse detection and diagnosis and calibration.
In general, the ADC result is affected by the environment, such as power supply voltage, reference voltage, input analog voltage, temperature, and noise. Therefore, calibration and averaging of the multiple ADC results are recommended to mitigate the influence of the environment.
To understand the functionality described and terminology used in this application note, see the “SAR ADC” chapter of the architecture technical reference manual (TRM)
Software trigger procedure
Figure 1 shows an example application that converts the given voltage values to pin ADC[0]_0 of the MCU to digital values. Analog-to-digital conversion is repeated in the interrupt service routine by using a software trigger.
Figure 1. Example of analog-to-digital conversion connection

To implement this application, use the following sections that describe the procedure for setting the ADC channel. These sections also provide an example for using a software trigger.
Basic ADC global settings
This section describes how to configure the ADC based on a use case using the sample driver library (SDL). The code snippets in this application note are part of SDL. See Other references.
SDL has a configuration part and a driver part. The configuration part configures the parameter values for the desired operation. The driver part configures each register based on the parameter values in the configuration part. You can configure the configuration part according to your system.
ADC global settings
The following are the procedures to configure common ADC settings in each channel:
- ADC enable and auto idle power down setting by the SARn_CTL register
- Debug freeze setting by the PASS_PASS_CTL register
Figure 2 shows an example of the ADC global settings.
Figure 2. Example of ADC global settings

Use case
The following use case is an example of ADC global setting:
- ADC logical channel: 0
- ADC operation frequency: 26.67 MHz
- Auto idle power down: 0 (Disable)
- Power-up time: 0 (Disable)
- SAR IP: 1 (Enable)
- SAR ADC and SARSEQ: 1(Enable)
- SARMUX: 1 (Enable)
Configuration
Table 1 lists the parameters and Table 2 lists the functions of the configuration part of in SDL for ADC global settings.
Table 1. List of ADC global settings parameters
Parameters | Description | Value |
|---|---|---|
| Analog macro for the potentiometer on the TRAVEO™ T2G baseboard | CY_ADC_POT_MACRO: PASS0_SAR0 |
| Bad parameter was passed | 0x01ul |
| Freezes ADC0 in debug mode | 0ul |
| Freezes ADC1 in debug mode | 0ul |
| Freezes ADC2 in debug mode | 0ul |
| Freezes ADC3 in debug mode | 0ul |
| Pre-condition time | 0ul |
| Power-up time | 0ul |
| Enables idle power down | false |
| MSB stretch mode 0: CY_ADC_MSB_STRETCH_MODE_1CYCLE 1: CY_ADC_MSB_STRETCH_MODE_2CYCLE | 1ul |
| Enables the half-LSB conversion | 0ul |
| Enables SAR MUX | true |
| Enables ADC | true |
| Enables SAR IP | true |
Table 2. List of ADC global settings functions
Functions | Description | Value |
|---|---|---|
| Initializes the ADC module | PASS SAR = BB_POTI_ANALOG_MACRO ADC Configure = adcConfig |
Sample code
This section demonstrates a sample code for the initial configuration of ADC global settings. The following description will help you understand the register notation of the driver part of the SDL:
-
base->unENABLE.stcField.u1CHAN_EN is the PASS0_SAR0_CH0_ENABLE.CHAN_EN setting mentioned in the registers TRM. Other registers are also described in the same manner.
-
Performance improvement measures: To improve the performance of register setting, the SDL writes a complete 32-bit data to the register. Each bit field is generated in advance in a bit-writable buffer and written to the register as the final 32-bit data.
unPostCtl.u32Register = base->unPOST_CTL.u32Register; unPostCtl.stcField.u3POST_PROC = config->postProcessingMode; unPostCtl.stcField.u1LEFT_ALIGN = config->resultAlignment; unPostCtl.stcField.u1SIGN_EXT = config->signExtention; unPostCtl.stcField.u8AVG_CNT = config->averageCount; unPostCtl.stcField.u5SHIFT_R = config->rightShift; unPostCtl.stcField.u2RANGE_MODE = config->rangeDetectionMode; unPostCtl.stcField.u5SHIFT_R = config->rightShift; unPostCtl.stcField.u2RANGE_MODE = config->rangeDetectionMode; base->unPOST_CTL.u32Register = unPostCtl.u32Register;
See cyip_pass.h under hdr/rev_x/ip for more information on the union and structure representation of registers.
Code Listing 1 General configuration of ADC global settings
:
#define BB_POTI_ANALOG_MACRO CY_ADC_POT_MACRO
:
/* Control freeze feature for debugging. */
cy_stc_adc_debug_freeze_config_t FreezeConfig =
{
/* If true, freeze ADC0 in debug mode. */
.enableFreezeAdc0 = 0ul,
.enableFreezeAdc1 = 0ul,
.enableFreezeAdc2 = 0ul,
.enableFreezeAdc3 = 0ul,
};
:
int main(void)
{
:
__enable_irq(); /* Enable global interrupts. */
/* Initialize ADC */
{
cy_stc_adc_config_t adcConfig = /* ADC Configuration.*/
{
.preconditionTime = 0ul,
.powerupTime = 0ul,
.enableIdlePowerDown = false,
.msbStretchMode = CY_ADC_MSB_STRETCH_MODE_2CYCLE,
.enableHalfLsbConv = 0ul,
.sarMuxEnable = true,
.adcEnable = true,
.sarIpEnable = true,
};
Cy_Adc_Init(BB_POTI_ANALOG_MACRO, &adcConfig); /* ADC Initialize. See Code Listing 2. */
Cy_Adc_SetDebugFreezeMode(PASS0_EPASS_MMIO,&FreezeConfig); /* Set Debug freeze mode. See Code Listing 3. */
:
}
:
for(;;)
{
}
}
Code Listing 2 Cy_Adc_Init() function
cy_en_adc_status_t Cy_Adc_Init(volatile stc_PASS_SAR_t * base, const cy_stc_adc_config_t * config)
{
cy_en_adc_status_t ret = CY_ADC_SUCCESS;
un_PASS_SAR_CTL_t unSarCtl = { 0 };
if (NULL != config)
{
/* CTL register setting */
base->unPRECOND_CTL.stcField.u4PRECOND_TIME = config->preconditionTime;
/* CTL register setting */ /* (1) Enable DC Setting. Auto Idle Power Down Setting. */
unSarCtl.stcField.u8PWRUP_TIME = config->powerupTime;
unSarCtl.stcField.u1IDLE_PWRDWN = config->enableIdlePowerDown ? 1ul : 0ul;
unSarCtl.stcField.u1MSB_STRETCH = config->msbStretchMode;
unSarCtl.stcField.u1HALF_LSB = config->enableHalfLsbConv ? 1ul : 0ul;
unSarCtl.stcField.u1SARMUX_EN = config->sarMuxEnable ? 1ul : 0ul;
unSarCtl.stcField.u1ADC_EN = config->adcEnable ? 1ul : 0ul;
unSarCtl.stcField.u1ENABLED = config->sarIpEnable ? 1ul : 0ul;
base->unCTL.u32Register = unSarCtl.u32Register;
}
else
{
ret = CY_ADC_BAD_PARAM;
}
return ret;
}
Code Listing 3 Cy_Adc_SetDebugFreezeMode () function
cy_en_adc_status_t Cy_Adc_SetDebugFreezeMode(volatile stc_PASS_EPASS_MMIO_t * base, const cy_stc_adc_debug_freeze_config_t * config)
{
cy_en_adc_status_t ret = CY_ADC_SUCCESS;
uint32_t temp = 0ul;
if (NULL != config)
{
temp |= (config->enableFreezeAdc0) ? 1ul : 0ul;
temp |= (config->enableFreezeAdc1) ? 2ul : 0ul;
temp |= (config->enableFreezeAdc2) ? 4ul : 0ul;
temp |= (config->enableFreezeAdc3) ? 8ul : 0ul;
base->unPASS_CTL.stcField.u4DBG_FREEZE_EN = temp; /* (2) Debug Freeze disabled by default. */
}
else
{
ret = CY_ADC_BAD_PARAM;
}
return ret;
}
Logical channel settings with software trigger
Each logical channel has one A/D conversion result register. A logical channel can be assigned as any analog input (ADC[n]_i) by setting the SARn_CHx_SAMPLE_CTL register.
Figure 3 shows the example of logical channel setting with a software trigger. In this example, the minimum value of the sample time is used. To find the proper sample time for your system, see the datasheet mentioned in Related documents.
Figure 3. Example of logical channel setting with software trigger

Logical channel 0 is used in this example. Any logical channel will work in this application if a proper analog input is selected.
Use case
The following use case is an example of logical channel setting with software trigger.
- Analog input: ADC[0]_0
- Sample time: 412.5 ns = 11 / (80 MHz /3)
- ADC trigger selection: OFF
- Channel priority: 0 (highest)
- Channel pre-emption type: Finish resume
- Channel group: The last channel
- ADC done level: Pulse
- ADC pin/port address: ADC[0]_0
- External analog MUX: 0, Enable
- Pre-conditioning mode: OFF
- Overlap diagnostics mode: OFF
- Calibration value select: Regular
- Post processing mode: None
- Result alignment: Right
- Sign extension: Unsigned
- Averaging count: 0
- Shift right: 0
- Mask group: Done/Not cancelled/Not overflow
- Mask channel: Not range/Not pulse/Not overflow
Configuration
Table 3 lists the parameters and Table 4 lists the functions of the configuration part of in SDL for logical channel settings with software trigger.
Table 3. Logical channel settings with software trigger parameters
Parameters | Description | Value |
|---|---|---|
| Analog macro for the potentiometer on the TRAVEO™ T2G baseboard | CY_ADC_POT_MACRO: PASS0_SAR0 |
| Analog input number for the potentiometer on the TRAVEO™ T2G baseboard | CH0 (CH[ADC_LOGICAL_CHANNEL]) |
| MSB stretch mode | 1ul (See Table 1) |
| Trigger OFF 0: CY_ADC_TRIGGER_OFF 1: CY_ADC_TRIGGER_TCPWM 2: CY_ADC_TRIGGER_GENERIC0 3: CY_ADC_TRIGGER_GENERIC1 4: CY_ADC_TRIGGER_GENERIC2 5: CY_ADC_TRIGGER_GENERIC3 6: CY_ADC_TRIGGER_GENERIC4 7: CY_ADC_TRIGGER_CONTINUOUS | 0ul |
| Channel priority | 0ul |
| Pre-emption type 0: CY_ADC_PREEMPTION_ABORT_CANCEL 1: CY_ADC_PREEMPTION_ABORT_RESTART 2: CY_ADC_PREEMPTION_ABORT_RESUME 3: CY_ADC_PREEMPTION_FINISH_RESUME | 3ul |
| Is group end? | true |
| Done level 0: CY_ADC_DONE_LEVEL_PULSE 1: CY_ADC_DONE_LEVEL_LEVEL | 0ul |
| Pin address | BB_POTI_ANALOG_INPUT_NO |
| Port address 0: CY_ADC_PORT_ADDRESS_SARMUX0 1: CY_ADC_PORT_ADDRESS_SARMUX1 2: CY_ADC_PORT_ADDRESS_SARMUX2 3: CY_ADC_PORT_ADDRESS_SARMUX3 | 0ul |
| External MUX select | 0ul |
| Enables external MUX | true |
| Pre-condition mode 0: CY_ADC_PRECONDITION_MODE_OFF 1: CY_ADC_PRECONDITION_MODE_VREFL 2: CY_ADC_PRECONDITION_MODE_VREFH 3: CY_ADC_PRECONDITION_MODE_DIAG | 0ul |
| Overlap diagnostics mode 0: CY_ADC_OVERLAP_DIAG_MODE_OFF 1: CY_ADC_OVERLAP_DIAG_MODE_HALF 2: CY_ADC_OVERLAP_DIAG_MODE_FULL 3: CY_ADC_OVERLAP_DIAG_MODE_MUX_DIAG | 0ul |
| Sample time | samplingCycle (Calculated Value) |
| Calibration value select 0: CY_ADC_CALIBRATION_VALUE_REGULAR 1: CY_ADC_CALIBRATION_VALUE_ALTERNATE | 0ul |
| Post-processing mode 0: CY_ADC_POST_PROCESSING_MODE_NONE 1: CY_ADC_POST_PROCESSING_MODE_AVG 2: CY_ADC_POST_PROCESSING_MODE_AVG_RANGE 3: CY_ADC_POST_PROCESSING_MODE_RANGE 4: CY_ADC_POST_PROCESSING_MODE_RANGE_PULSE | 0ul |
| Result alignment 0: CY_ADC_RESULT_ALIGNMENT_RIGHT 1: CY_ADC_RESULT_ALIGNMENT_LEFT | 0ul |
| Sign extension 0: CY_ADC_SIGN_EXTENTION_UNSIGNED 1: CY_ADC_SIGN_EXTENTION_SIGNED | 0ul |
| Average count | 0ul |
| Right shift | 0ul |
| Range detection mode 0: CY_ADC_RANGE_DETECTION_MODE_BELOW_LO 1: CY_ADC_RANGE_DETECTION_MODE_INSIDE_RANGE 2: CY_ADC_RANGE_DETECTION_MODE_ABOVE_HI 3: CY_ADC_RANGE_DETECTION_MODE_OUTSIDE_RANGE | 1ul |
| Range detection low threshold | 0x0000ul |
| Range detection high threshold | 0x0FFFul |
| Mask group done | true |
| Mask group cancelled | false |
| Mask group overflow | false |
| Mask channel range | false |
| Mask channel pulse | false |
| Mask channel overflow | false |
Table 4. Functions for logical channel settings with software trigger
Functions | Description | Value |
|---|---|---|
| Initializes the ADC channel | PASS SARchannel = &BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL] ADCchannel Configure = adcChannelConfig |
| Sets the ADC channel interrupt mask | PASS SARchannel = base INTR Source = mask |
| Initializes the referenced system interrupt by setting the interrupt vector | Config = irq_cfg |
| Enables the corresponding channel | SARchannel = PASS_SAR_CH |
| Issues a software start trigger | PASS SARchannel = &BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL] |
Sample code
See Code Listing 4 to Code Listing 9 for sample code for initial configuration of logical channel settings with software trigger settings.
Code Listing 4 General configuration of ADC global settings
:
#define BB_POTI_ANALOG_MACRO CY_ADC_POT_MACRO
#define BB_POTI_ANALOG_INPUT_NO ((cy_en_adc_pin_address_t)CY_ADC_POT_IN_NO)
:
int main(void)
{
:
__enable_irq(); /* Enable global interrupts. */
/* Initialize ADC */
{
:
cy_stc_adc_config_t adcConfig = /* ADC Configuration.*/
{
.preconditionTime = 0ul,
.powerupTime = 0ul,
.enableIdlePowerDown = false,
.msbStretchMode = CY_ADC_MSB_STRETCH_MODE_2CYCLE,
.enableHalfLsbConv = 0ul,
.sarMuxEnable = true,
.adcEnable = true,
.sarIpEnable = true,
};
cy_stc_adc_channel_config_t adcChannelConfig =
{
.triggerSelection = CY_ADC_TRIGGER_OFF, /* Trigger type setting */
.channelPriority = 0ul, /* (1) Logical channel priority setting */
.preenptionType = CY_ADC_PREEMPTION_FINISH_RESUME, /* Preemption type setting */
.isGroupEnd = true, /* Group End setting */
.doneLevel = CY_ADC_DONE_LEVEL_PULSE, /* Level or pulse selection */
.pinAddress = BB_POTI_ANALOG_INPUT_NO, /* (2) Analog input setting, Sample time setting */
.portAddress = CY_ADC_PORT_ADDRESS_SARMUX0, /* (2) Analog input setting, Sample time setting */
.extMuxSelect = 0ul, /* (2) Analog input setting, Sample time setting */
.extMuxEnable = true, /* (2) Analog input setting, Sample time setting */
.preconditionMode = CY_ADC_PRECONDITION_MODE_OFF, /* (2) Analog input setting, Sample time setting */
.overlapDiagMode = CY_ADC_OVERLAP_DIAG_MODE_OFF, /* (2) Analog input setting, Sample time setting */
.sampleTime = 0ul, /* (2) Analog input setting, Sample time setting */
.calibrationValueSelect = CY_ADC_CALIBRATION_VALUE_REGULAR, /* (2) Analog input setting, Sample time setting */
.postProcessingMode = CY_ADC_POST_PROCESSING_MODE_NONE, /* (2) Analog input setting, Sample time setting */
.resultAlignment = CY_ADC_RESULT_ALIGNMENT_RIGHT, /* (2) Analog input setting, Sample time setting */
.signExtention = CY_ADC_SIGN_EXTENTION_UNSIGNED, /* (2) Analog input setting, Sample time setting */
.averageCount = 0ul, /* (2) Analog input setting, Sample time setting */
.rightShift = 0ul, /* (2) Analog input setting, Sample time setting */
.rangeDetectionMode = CY_ADC_RANGE_DETECTION_MODE_INSIDE_RANGE,
.rangeDetectionLoThreshold = 0x0000ul, /* Continuation of (2) */
.rangeDetectionHiThreshold = 0x0FFFul, /* Continuation of (2) */
.mask.grpDone = true, /* (3) Interrupt mask setting */
.mask.grpCancelled = false, /* (3) Interrupt mask setting */
.mask.grpOverflow = false, /* (3) Interrupt mask setting */
.mask.chRange = false, /* (3) Interrupt mask setting */
.mask.chPulse = false, /* (3) Interrupt mask setting */
.mask.chOverflow = false, /* (3) Interrupt mask setting */
};
Cy_Adc_Init(BB_POTI_ANALOG_MACRO, &adcConfig); /* ADC Initialize. See Code Listing 2 */
Cy_Adc_Channel_Init(&BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL], &adcChannelConfig); /* Initialize ADC Channel. See Code Listing 5. */
}
:
Cy_SysInt_InitIRQ(&irq_cfg); /* Initialize Interrupt Request. See Code Listing 7 */
:
/* Enable ADC ch. */ /* Enable ADC Channel. See Code Listing 8 */
Cy_Adc_Channel_Enable(&BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL]);
/* Issue SW trigger */
Cy_Adc_Channel_SoftwareTrigger(&BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL]); /* Software Trigger Setting. See Code Listing 9 */
for(;;)
{
}
}
Code Listing 5 Cy_Adc_Channel_Init() function
cy_en_adc_status_t Cy_Adc_Channel_Init(volatile stc_PASS_SAR_CH_t * base, const cy_stc_adc_channel_config_t * config)
{
cy_en_adc_status_t ret = CY_ADC_SUCCESS;
un_PASS_SAR_CH_TR_CTL_t unTrCtl = { 0ul };
un_PASS_SAR_CH_SAMPLE_CTL_t unSampleCtl = { 0ul };
un_PASS_SAR_CH_POST_CTL_t unPostCtl = { 0ul };
un_PASS_SAR_CH_RANGE_CTL_t unRangeCtl = { 0ul };
un_PASS_SAR_CH_INTR_t unIntr = { 0ul };
if (NULL != config)
{
:
/* Clear whole interrupt flags */
unIntr.stcField.u1CH_OVERFLOW = 1ul;
unIntr.stcField.u1CH_PULSE = 1ul;
unIntr.stcField.u1CH_RANGE = 1ul;
unIntr.stcField.u1GRP_CANCELLED = 1ul;
unIntr.stcField.u1GRP_DONE = 1ul;
unIntr.stcField.u1GRP_OVERFLOW = 1ul;
base->unINTR.u32Register = unIntr.u32Register;
unTrCtl.stcField.u3SEL = config->triggerSelection;
unTrCtl.stcField.u3PRIO = config->channelPriority;
unTrCtl.stcField.u2PREEMPT_TYPE = config->preenptionType;
unTrCtl.stcField.u1GROUP_END = config->isGroupEnd ? 1ul : 0ul;
unTrCtl.stcField.u1DONE_LEVEL = config->doneLevel ? 1ul : 0ul;
base->unTR_CTL.u32Register = unTrCtl.u32Register;
unSampleCtl.stcField.u6PIN_ADDR = config->pinAddress;
unSampleCtl.stcField.u2PORT_ADDR = config->portAddress;
unSampleCtl.stcField.u3EXT_MUX_SEL = config->extMuxSelect;
unSampleCtl.stcField.u1EXT_MUX_EN = config->extMuxEnable ? 1ul : 0ul;
unSampleCtl.stcField.u2PRECOND_MODE = config->preconditionMode;
unSampleCtl.stcField.u2OVERLAP_DIAG = config->overlapDiagMode;
unSampleCtl.stcField.u12SAMPLE_TIME = config->sampleTime;
unSampleCtl.stcField.u1ALT_CAL = config->calibrationValueSelect;
base->unSAMPLE_CTL.u32Register = unSampleCtl.u32Register;
unPostCtl.stcField.u3POST_PROC = config->postProcessingMode;
unPostCtl.stcField.u1LEFT_ALIGN = config->resultAlignment;
unPostCtl.stcField.u1SIGN_EXT = config->signExtention;
unPostCtl.stcField.u8AVG_CNT = config->averageCount;
unPostCtl.stcField.u5SHIFT_R = config->rightShift;
unPostCtl.stcField.u2RANGE_MODE = config->rangeDetectionMode;
base->unPOST_CTL.u32Register = unPostCtl.u32Register;
unRangeCtl.stcField.u16RANGE_LO = config->rangeDetectionLoThreshold;
unRangeCtl.stcField.u16RANGE_HI = config->rangeDetectionHiThreshold;
base->unRANGE_CTL.u32Register = unRangeCtl.u32Register;
Cy_Adc_Channel_SetInterruptMask(base, &config->mask); /* ADC Channel Set Interrupt Mask. See Code Listing 6 */
}
else
{
ret = CY_ADC_BAD_PARAM;
}
return ret;
}
Code Listing 6 Cy_Adc_Channel_SetInterruptMask() function
cy_en_adc_status_t Cy_Adc_Channel_SetInterruptMask(volatile stc_PASS_SAR_CH_t * base, const cy_stc_adc_interrupt_source_t * mask)
{
cy_en_adc_status_t ret = CY_ADC_SUCCESS;
un_PASS_SAR_CH_INTR_MASK_t unMask = { 0ul };
if (NULL != mask)
{
unMask.stcField.u1CH_OVERFLOW_MASK = mask->chOverflow ? 1ul : 0ul;
unMask.stcField.u1CH_PULSE_MASK = mask->chPulse ? 1ul : 0ul;
unMask.stcField.u1CH_RANGE_MASK = mask->chRange ? 1ul : 0ul;
unMask.stcField.u1GRP_CANCELLED_MASK = mask->grpCancelled ? 1ul : 0ul;
unMask.stcField.u1GRP_DONE_MASK = mask->grpDone ? 1ul : 0ul;
unMask.stcField.u1GRP_OVERFLOW_MASK = mask->grpOverflow ? 1ul : 0ul;
base->unINTR_MASK.u32Register = unMask.u32Register;
}
else
{
ret = CY_ADC_BAD_PARAM;
}
return ret;
}
Code Listing 7 Cy_SysInt_InitIRQ() function
cy_en_sysint_status_t Cy_SysInt_InitIRQ(const cy_stc_sysint_irq_t* config)
{
cy_en_sysint_status_t status = CY_SYSINT_SUCCESS;
#if (CY_CPU_CORTEX_M0P)
un_CPUSS_CM0_SYSTEM_INT_CTL_t unIntCtl = { 0ul };
#else
#if defined (tviibe512k) || defined (tviibe1m) || defined (tviibe2m)|| defined (tviibe4m)
un_CPUSS_CM4_SYSTEM_INT_CTL_t unIntCtl = { 0ul };
#elif defined (tviibh4m) || defined (tviibh8m) || defined (tviic2d6m) || defined (tviic2d4m) || defined (tviic2d6mddr)
un_CPUSS_CM7_0_SYSTEM_INT_CTL_t unIntCtl0 = { 0ul };
un_CPUSS_CM7_1_SYSTEM_INT_CTL_t unIntCtl1 = { 0ul };
#endif
#endif
if(NULL != config)
{
#if (CY_CPU_CORTEX_M0P) //rmkn u3CM0_CPU_INT_IDX->u3CPU_INT_IDX
#if defined (tviibe512k) || defined (tviibe1m) || defined (tviibe2m)|| defined (tviibe4m)
unIntCtl.stcField.u3CPU_INT_IDX = (uint8_t)config->intIdx;
#elif defined (tviibh4m) || defined (tviibh8m) || defined (tviic2d6m) || defined (tviic2d4m) || defined (tviic2d6mddr)
unIntCtl.stcField.u3CM0_CPU_INT_IDX = (uint8_t)config->intIdx;
#endif
unIntCtl.stcField.u1CPU_INT_VALID = config->isEnabled ? 1ul : 0ul;
CPUSS->unCM0_SYSTEM_INT_CTL[config->sysIntSrc].u32Register = unIntCtl.u32Register;
#else
#if defined (tviibe512k) || defined (tviibe1m) || defined (tviibe2m)|| defined (tviibe4m)
unIntCtl.stcField.u3CPU_INT_IDX = (uint8_t)config->intIdx;
unIntCtl.stcField.u1CPU_INT_VALID = config->isEnabled ? 1ul : 0ul;
CPUSS->unCM4_SYSTEM_INT_CTL[config->sysIntSrc].u32Register = unIntCtl.u32Register; /* (4) Set Interrupt Enable of CM4, Interrupt structure setting, Priority setting, Clear pending status and Enable IRQ. */
#elif defined (tviibh4m) || defined (tviibh8m) || defined (tviic2d6m) || defined (tviic2d4m) || defined (tviic2d6mddr)
if(CPUSS->unIDENTITY.stcField.u4MS == CPUSS_MS_ID_CM7_0)
{
unIntCtl0.stcField.u4CPU_INT_IDX = (uint8_t)config->intIdx;
unIntCtl0.stcField.u1CPU_INT_VALID = config->isEnabled ? 1ul : 0ul;
CPUSS->unCM7_0_SYSTEM_INT_CTL[config->sysIntSrc].u32Register = unIntCtl0.u32Register;
}
else // should be CPUSS_MS_ID_CM7_1
{
unIntCtl1.stcField.u4CPU_INT_IDX = (uint8_t)config->intIdx;
unIntCtl1.stcField.u1CPU_INT_VALID = config->isEnabled ? 1ul : 0ul;
CPUSS->unCM7_1_SYSTEM_INT_CTL[config->sysIntSrc].u32Register = unIntCtl1.u32Register;
}
#endif
#endif
}
else
{
status = CY_SYSINT_BAD_PARAM;
}
return(status);
}
Code Listing 8 Cy_Adc_Channel_Enable() function
void Cy_Adc_Channel_Enable(volatile stc_PASS_SAR_CH_t * base)
{
base->unENABLE.stcField.u1CHAN_EN = 1ul; /* (5) Enable Channel 0. */
}
Code Listing 9 Cy_Adc_Channel_SoftwareTrigger() function
void Cy_Adc_Channel_SoftwareTrigger(volatile stc_PASS_SAR_CH_t * base)
{
base->unTR_CMD.stcField.u1START = 1ul; /* (6) Enable Software Trigger. */
}
A/D conversion ISR with software trigger
Figure 4 shows the example of ADC ISR with a software trigger. For details on CPU interrupt handling, see the architecture TRM mentioned in Related documents.
Figure 4. Example of ADC ISR with software trigger

Use case
See Section 2.3.1.
Configuration
Table 5 lists the parameters and Table 6 lists the functions of the configuration part of in SDL for ADC Global settings.
Table 5. Parameters for ADC ISR with software trigger
Parameters | Description | Value |
|---|---|---|
| Analog macro for the potentiometer on TRAVEO™ T2G baseboard | CY_ADC_POT_MACRO: PASS0_SAR0 |
| Conversion result buffer | - (Calculated Value) |
| Status result buffer | - (Calculated Value) |
| Index result | - (Calculated Value) |
| Interrupt source | - (Calculated Value) |
Table 6. Functions for ADC ISR with software trigger
Functions | Description | Value |
|---|---|---|
| Gets the conversion result and status | SAR Channel = BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL], Result = resultBuff[resultIdx], Status= statusBuff[resultIdx] |
| Clears the corresponding channel interrupt status | SAR Channel = BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL], Source = intrSource |
| Issues the software start trigger | SAR Channel = BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL] |
Sample code
See Code Listing 10 to Code Listing 12 for sample code for initial configuration of ADC ISR with software trigger.
Code Listing 10 ADC ISR with software trigger
#define BB_POTI_ANALOG_MACRO CY_ADC_POT_MACRO
:
uint16_t resultBuff[16];
cy_stc_adc_ch_status_t statusBuff[16];
uint8_t resultIdx;
:
void AdcIntHandler(void)
{
cy_stc_adc_interrupt_source_t intrSource = { false };
:
{
/* Get the result(s) */ /* (1) Read A/D conversion data. See Code Listing 11. */
Cy_Adc_Channel_GetResult(&BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL], &resultBuff[resultIdx], &statusBuff[resultIdx]);
/* Display ADC result */
printf("\rADC result = %04d ", resultBuff[resultIdx]);
/* Increment result idx */
resultIdx = (resultIdx + 1) % (sizeof(resultBuff) / sizeof(resultBuff[0]));
/* Clear interrupt source */ /* (2) Clear and read A/D conversion flag. See Code Listing 12. */
Cy_Adc_Channel_ClearInterruptStatus(&BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL], &intrSource);
/* Trigger next conversion */
Cy_Adc_Channel_SoftwareTrigger(&BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL]); /* (3) Software Trigger Setting. See Code Listing 9. */
}
else
{
// Unexpected interrupt
CY_ASSERT(false);
}
}
Code Listing 11 Cy_Adc_Channel_GetResult() function
Cy_Adc_Channel_GetResult(const volatile stc_PASS_SAR_CH_t * base, uint16_t * result, cy_stc_adc_ch_status_t * status)
{
cy_en_adc_status_t ret = CY_ADC_SUCCESS;
un_PASS_SAR_CH_RESULT_t value;
if ((NULL != result) && (NULL != status))
{
value.u32Register = base->unRESULT.u32Register;
*result = value.stcField.u16RESULT;
status->aboveHi = (value.stcField.u1ABOVE_HI_MIR != 0ul) ? true : false;
status->pulseIntr = (value.stcField.u1PULSE_INTR_MIR != 0ul) ? true : false;
status->rangeIntr = (value.stcField.u1RANGE_INTR_MIR != 0ul) ? true : false;
status->valid = (value.stcField.u1VALID_MIR != 0ul) ? true : false;
}
else
{
ret = CY_ADC_BAD_PARAM;
}
return ret;
}
Code Listing 12 Cy_Adc_Channel_ClearInterruptStatus() function
cy_en_adc_status_t Cy_Adc_Channel_ClearInterruptStatus(volatile stc_PASS_SAR_CH_t * base, const cy_stc_adc_interrupt_source_t * source)
{
cy_en_adc_status_t ret = CY_ADC_SUCCESS;
un_PASS_SAR_CH_INTR_t unIntr = { 0ul };
if (NULL != source)
{
unIntr.stcField.u1CH_OVERFLOW = source->chOverflow ? 1ul : 0ul;
unIntr.stcField.u1CH_PULSE = source->chPulse ? 1ul : 0ul;
unIntr.stcField.u1CH_RANGE = source->chRange ? 1ul : 0ul;
unIntr.stcField.u1GRP_CANCELLED = source->grpCancelled ? 1ul : 0ul;
unIntr.stcField.u1GRP_DONE = source->grpDone ? 1ul : 0ul;
unIntr.stcField.u1GRP_OVERFLOW = source->grpOverflow ? 1ul : 0ul;
base->unINTR.u32Register = unIntr.u32Register;
}
else
{
ret = CY_ADC_BAD_PARAM;
}
return ret;
}
Hardware trigger procedure
The SAR ADC can be triggered by other related hardware functions, such as TCPWM, GPIO, and event generator.
This section explains the example application that converts the voltage values given to ADC[0]_0 pin of the MCU to digital values. The analog-to-digital conversion is repeated at regular intervals by hardware trigger of a corresponding TCPWM.
The physical setting of this application is the same as shown in Figure 1.
Ensure that you have set up the parameters as mentioned in Basic ADC global settings.
To implement this application, follow the procedure of ADC channel setting and its example when using a hardware trigger. The example in this section uses a corresponding TCPWM for the trigger.
Logical channel setting with hardware trigger
Figure 5 shows the example of logical channel setting with a hardware trigger in CYT2 series. In this example, the minimum value of the sample time is used. To find the proper sample time for your system, see the datasheet mentioned in Related documents.
Figure 5. Example of logical channel setting with hardware trigger in CYT2
series

Logical channel 0 is used in this example. Any logical channel will work in this application if a proper analog input is selected. Also, TCPWM and the trigger multiplexer should be configured.
Use case
The following use case is an example of logical channel setting with hardware trigger:
- Analog input: ADC[0]_0
- Sample time: 412.5 ns = 11 / (80 MHz /3)
- Trigger select: TCPWM
- Pre-emption type: FINISH_RESUME
- GROUP_END: Last channel of a group
- External analog MUX: 0, Enable
- Pre-conditioning mode: OFF
- Overlap diagnostics mode: OFF
- Calibration value select: Regular
- Post processing mode: None
- Result alignment: Right
- Sign extension: Unsigned
- Averaging count: 0
- Shift right: 0
- Mask group: Done/Not cancelled/Not overflow
- Mask channel: Not range/Not pulse/Not overflow
Configuration
Table 7 lists the parameters and Table 8 lists the functions of the configuration part of in SDL for Logical Channel Setting with Hardware Trigger in CYT2 Series settings.
Table 7. Parameters for logical channel setting with hardware trigger
in CYT2 series
Parameters | Description | Value |
|---|---|---|
| Analog macro for the potentiometer on the TRAVEO™ T2G baseboard | CY_ADC_POT_MACRO: PASS0_SAR0 |
| Strong drive, Input buffer off | 0x06ul |
| Pin output state | 0ul |
| Drive mode | CY_GPIO_DM_STRONG_IN_OFF |
| High-speed I/O matrix selection | TCPWMx_LINEx_MUX |
| Interrupt edge type | 0ul |
| Interrupt enable mask | 0ul |
| Input buffer voltage trip type | 0ul |
| Output buffer slew rate | 0ul |
| Drive strength | 0ul |
| Analog High-Z, input buffer off | 0x00ul |
| Pin output state | 0ul |
| Drive Mode | CY_GPIO_DM_ANALOG |
| High-speed I/O matrix selection | P6_0_GPIO |
| Interrupt edge type | 0ul |
| Interrupt enable mask | 0ul |
| Input buffer voltage trip type | 0ul |
| Output buffer slew rate | 0ul |
| Drive strength | 0ul |
| Pre-condition time | 0ul |
| Power-up time | 0ul |
| Enables idle power down | false |
| MSB stretch mode | 1ul (See Table 1) |
| Enables half LSB conversion | 0ul |
| Enables SAR MUX | true |
| Enables ADC | true |
| Enables SAR IP | true |
| Trigger selection | 1ul (See Table 3) |
| Channel priority | 0ul |
| Pre-emption type | 3ul (See Table 3) |
| Is group end? | true |
| Done level | 0ul (See Table 3) |
| Pin address | BB_POTI_ANALOG_INPUT_NO |
| Port address | 0ul (See Table 3) |
| External MUX select | 0ul |
| Enable external MUX | true |
| Pre-condition mode | 0ul (See Table 3) |
| Overlap diagnostics mode | 0ul (See Table 3) |
| Sample time | 0ul |
| Calibration value select | 0ul (See Table 3) |
| Post processing mode | 0ul (See Table 3) |
| Result alignment | 0ul (See Table 3) |
| Sign extension | 0ul (See Table 3) |
| Average count | 0ul |
| Right shift | 0ul |
| Range detection mode | 1ul (See Table 3) |
| Range detection low threshold | 0x0000ul |
| Range detection high threshold | 0x0FFFul |
| Mask group done | true |
| Mask group cancelled | false |
| Mask group overflow | false |
| Mask channel range | false |
| Mask channel pulse | false |
| Mask channel overflow | false |
Table 8. Functions for logical channel setting with hardware trigger in
CYT2 series
Functions | Description | Value |
|---|---|---|
| Returns the interrupt status | PASS SARchannel = &BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL] INTR Source = &intrSource |
| Changes the User ISR vector for the system interrupt | Source = sysIntSrc INTR handler = AdcIntHandler |
| Initializes all pin configuration settings for the pin | Port Number = TCPWMx_LINEx_PORT Pin Number = TCPWMx_LINEx_PIN gpio_pin_config = TCPWMx_LINEx_PIN, &pin_cfg1 |
| Initializes the TCPWM for PWM operation | Group Counter = TCPWMx_GRPx_CNTx_PWM TCPWM PWM config = &MyPWM_config |
| De-initializes the TCPWM block | Group Counter = TCPWMx_GRPx_CNTx_PWM |
| Triggers a software start on selected TCPWMs | Group Counter = TCPWMx_GRPx_CNTx_PWM |
| Connects an input trigger source and output trigger | Trigger MUX = TRIG_IN_1TO1_1_TCPWM_TO_PASS_CH_TR0 Invert = 0ul Trigger Type = TRIGGER_TYPE_PASS_TR_SAR_CH_IN__EDGE Debug Freeze Enable = 0ul |
Sample code
See Code Listing 13 to Code Listing 20 for sample code for initial configuration of logical channel setting with hardware trigger in CYT2 series.
Code Listing 13 Logical channel setting with hardware trigger in CYT2 series
#define BB_POTI_ANALOG_MACRO PASS0_SAR0
:
#define DIV_ROUND_UP(a,b) (((a) + (b)/2) / (b))
/* A/D value result buff */
uint8_t resultIdx;
uint16_t resultBuff[16];
/* A/D Status */
cy_stc_adc_ch_status_t statusBuff[16];
/* PWM CONFIGURATION */
/* PWM Mode Configuration def */
#define TCPWMx_GRPx_CNTx_PWM TCPWM0_GRP1_CNT0
#define PCLK_TCPWMx_CLOCKSx_PWM PCLK_TCPWM0_CLOCKS256
#define TCPWM_PERI_CLK_DIVIDER_NO_PWM 0ul
#define TCPWMx_PWM_PRESCALAR_DIV_x CY_TCPWM_PWM_PRESCALER_DIVBY_128 // 2,000,000 / 128 = 15,625Hz
#define TCPWMx_PERIOD 0x1000 // 15,625Hz / 4096 (0x1000) = 3.815Hz (PWM frequency)
#define TCPWMx_COMPARE0 0x800 // 0x800 / 0x1000 = 0.5 (PWM duty)
/* TCPWM_LINE0 */
#define TCPWMx_LINEx_PORT GPIO_PRT3
#define TCPWMx_LINEx_PIN 5
#define TCPWMx_LINEx_MUX P3_5_TCPWM0_LINE256
/* PWM */
cy_stc_gpio_pin_config_t pin_cfg1 = /* GPIO Pin Configuration */
{
.outVal = 0ul,
.driveMode = CY_GPIO_DM_STRONG_IN_OFF,
.hsiom = TCPWMx_LINEx_MUX,
.intEdge = 0ul,
.intMask = 0ul,
.vtrip = 0ul,
.slewRate = 0ul,
.driveSel = 0ul,
};
cy_stc_tcpwm_pwm_config_t const MyPWM_config = /* TCPWM Configuration */
{
.pwmMode = CY_TCPWM_PWM_MODE_PWM,
.clockPrescaler = TCPWMx_PWM_PRESCALAR_DIV_x,
.debug_pause = false,
.Cc0MatchMode = CY_TCPWM_PWM_TR_CTRL2_CLEAR,
.OverflowMode = CY_TCPWM_PWM_TR_CTRL2_SET,
.UnderflowMode = CY_TCPWM_PWM_TR_CTRL2_NO_CHANGE,
.Cc1MatchMode = CY_TCPWM_PWM_TR_CTRL2_NO_CHANGE,
.deadTime = 0ul,
.deadTimeComp = 0ul,
.runMode = CY_TCPWM_PWM_CONTINUOUS,
.period = TCPWMx_PERIOD - 1ul,
.period_buff = 0ul,
.enablePeriodSwap = false,
.compare0 = TCPWMx_COMPARE0,
.compare1 = 0ul,
.enableCompare0Swap = false,
.enableCompare1Swap = false,
.interruptSources = 0ul,
.invertPWMOut = 0ul,
.invertPWMOutN = 0ul,
.killMode = CY_TCPWM_PWM_STOP_ON_KILL,
.switchInputMode = 3ul,
.switchInput = 0ul,
.reloadInputMode = 3ul,
.reloadInput = 0ul,
.startInputMode = 3ul,
.startInput = 0ul,
.kill0InputMode = 3ul,
.kill0Input = 0ul,
.kill1InputMode = 3ul,
.kill1Input = 0ul,
.countInputMode = 3ul,
.countInput = 1ul,
};
/* ADC CONFIGURATION */
/* ADC port setting (Note default port setting after reset is just fine) */
cy_stc_gpio_pin_config_t adcPinConfig = /* ADC Pin Configuration. */
{
.outVal = 0ul,
.driveMode = CY_GPIO_DM_ANALOG,
.hsiom = P6_0_GPIO,
.intEdge = 0ul,
.intMask = 0ul,
.vtrip = 0ul,
.slewRate = 0ul,
.driveSel = 0ul,
};
/* ADC Channel Configuration */
cy_stc_adc_config_t adcConfig = /* ADC Configuration. See Code Listing 2. */
{
.preconditionTime = 0ul,
.powerupTime = 0ul,
.enableIdlePowerDown = false,
.msbStretchMode = CY_ADC_MSB_STRETCH_MODE_2CYCLE,
.enableHalfLsbConv = 0ul,
.sarMuxEnable = true,
.adcEnable = true,
.sarIpEnable = true,
};
cy_stc_adc_channel_config_t adcChannelConfig = /* ADC Channel Configuration. See Code Listing 5. */
{
/* Trigger type: Trigger from corresponding TCPWM channel */
.triggerSelection = CY_ADC_TRIGGER_TCPWM, /* Trigger Type Setting */
.channelPriority = 0ul, /* (1) Logical Channel Priority Setting */
.preenptionType = CY_ADC_PREEMPTION_FINISH_RESUME, /* Preemption Type Setting */
.isGroupEnd = true, /* Group End Setting */
/* CY_ADC_DONE_LEVEL_PULSE = 0 */
.doneLevel = CY_ADC_DONE_LEVEL_PULSE, /* Level or Pulse Selection */
.pinAddress = BB_POTI_ANALOG_INPUT_NO, /* (2) Analog Input Setting, Sample Time Setting */
.portAddress = CY_ADC_PORT_ADDRESS_SARMUX0, /* (2) Analog Input Setting, Sample Time Setting */
.extMuxSelect = 0ul, /* (2) Analog Input Setting, Sample Time Setting */
.extMuxEnable = true, /* (2) Analog Input Setting, Sample Time Setting */
.preconditionMode = CY_ADC_PRECONDITION_MODE_OFF, /* (2) Analog Input Setting, Sample Time Setting */
.overlapDiagMode = CY_ADC_OVERLAP_DIAG_MODE_OFF, /* (2) Analog Input Setting, Sample Time Setting */
.sampleTime = 0ul, /* (2) Analog Input Setting, Sample Time Setting */
.calibrationValueSelect = CY_ADC_CALIBRATION_VALUE_REGULAR, /* (2) Analog Input Setting, Sample Time Setting */
.postProcessingMode = CY_ADC_POST_PROCESSING_MODE_NONE, /* (2) Analog Input Setting, Sample Time Setting */
.resultAlignment = CY_ADC_RESULT_ALIGNMENT_RIGHT, /* (2) Analog Input Setting, Sample Time Setting */
.signExtention = CY_ADC_SIGN_EXTENTION_UNSIGNED, /* (2) Analog Input Setting, Sample Time Setting */
.averageCount = 0ul, /* (2) Analog Input Setting, Sample Time Setting */
.rightShift = 0ul, /* (2) Analog Input Setting, Sample Time Setting */
.rangeDetectionMode = CY_ADC_RANGE_DETECTION_MODE_INSIDE_RANGE, /* (2) Analog Input Setting, Sample Time Setting */
.rangeDetectionLoThreshold = 0x0000ul, /* (2) Analog Input Setting, Sample Time Setting */
.rangeDetectionHiThreshold = 0x0FFFul, /* (2) Analog Input Setting, Sample Time Setting */
.mask.grpDone = true, /* (3) Interrupt Mask Setting */
.mask.grpCancelled = false, /* (3) Interrupt Mask Setting */
.mask.grpOverflow = false, /* (3) Interrupt Mask Setting */
.mask.chRange = false, /* (3) Interrupt Mask Setting */
.mask.chPulse = false, /* (3) Interrupt Mask Setting */
.mask.chOverflow = false, /* (3) Interrupt Mask Setting */
};
void AdcIntHandler(void)
{
cy_stc_adc_interrupt_source_t intrSource = { false };
/* Get interrupt source */
Cy_Adc_Channel_GetInterruptMaskedStatus(&BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL], &intrSource); /* Get Interrupt Masked Status. See Code Listing 14. */
if(intrSource.grpDone)
{
/* Get the result(s) */
Cy_Adc_Channel_GetResult(&BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL], &resultBuff[resultIdx], &statusBuff[resultIdx]); /* Read A/D conversion data. See Code Listing 11. */
/* Increment result idx */
resultIdx = (resultIdx + 1) % (sizeof(resultBuff) / sizeof(resultBuff[0]));
/* Clear interrupt source */
Cy_Adc_Channel_ClearInterruptStatus(&BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL], &intrSource); /* Clear and read A/D conversion flag. See Code Listing 12. */
}
else
{
/* Unexpected interrupt */
CY_ASSERT(false);
}
}
/* This is an ADC example file for HW trigger: TCPWM */
int main(void)
{
__enable_irq(); /* Enable global interrupts. */
SystemInit();
:
/* Initialize ADC */
uint32_t samplingCycle = (uint32_t)DIV_ROUND_UP((ANALOG_IN_SAMPLING_TIME_MIN_IN_NS * (uint64_t)actualAdcOperationFreq), 1000000000ull);
adcChannelConfig.sampleTime = samplingCycle;
Cy_Adc_Init(BB_POTI_ANALOG_MACRO, &adcConfig); /* ADC Initialize. See Code Listing 2 */
Cy_Adc_Channel_Init(&BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL], &adcChannelConfig); /* ADC Channel Initialize. See Code Listing 5. */
/* Register ADC interrupt handler and enable interrupt */
cy_stc_sysint_irq_t irq_cfg;
irq_cfg = (cy_stc_sysint_irq_t){
.sysIntSrc = pass_0_interrupts_sar_0_IRQn,
.intIdx = CPUIntIdx3_IRQn,
.isEnabled = true,
};
Cy_SysInt_InitIRQ(&irq_cfg); /* (4) Initialize Interrupt Request. See Code Listing 7. */
Cy_SysInt_SetSystemIrqVector(irq_cfg.sysIntSrc, AdcIntHandler); /* Initialize Interrupt Request. See Code Listing 15. */
NVIC_SetPriority(irq_cfg.intIdx, 0ul);
NVIC_EnableIRQ(irq_cfg.intIdx);
:
/* Port Configuration for TCPWM */ /* Initialize GPIO Pin. See Code Listing 16. */
Cy_GPIO_Pin_Init(TCPWMx_LINEx_PORT, TCPWMx_LINEx_PIN, &pin_cfg1);
/* Initialize TCPWM0_GRPx_CNTx_PWM_PR as PWM Mode & Enable */
Cy_Tcpwm_Pwm_Init(TCPWMx_GRPx_CNTx_PWM, &MyPWM_config); /* Initialize TCPWM PWM. See Code Listing 17. */
/* Enable ADC ch. and PWM */
Cy_Adc_Channel_Enable(&BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL]); /* (5) Enable ADC channel. See Code Listing 8. */
Cy_Tcpwm_Pwm_Enable(TCPWMx_GRPx_CNTx_PWM); /* TCPWM PWM Enable. See Code Listing 18. */
Cy_Tcpwm_TriggerStart(TCPWMx_GRPx_CNTx_PWM); / * TCPWM Trigger Start Select. See Code Listing 19 */
/* Trigger MUX */
Cy_TrigMux_Connect1To1(TRIG_IN_1TO1_1_TCPWM_TO_PASS_CH_TR0,
0ul,
TRIGGER_TYPE_PASS_TR_SAR_CH_IN__EDGE,
0ul); /* Connects an input trigger source and output trigger. See Code Listing 20. */
for(;;);
}
Code Listing 14 Cy_Adc_Channel_GetInterruptMaskedStatus() function
cy_en_adc_status_t Cy_Adc_Channel_GetInterruptStatus(const volatile stc_PASS_SAR_CH_t * base, cy_stc_adc_interrupt_source_t * status)
{
cy_en_adc_status_t ret = CY_ADC_SUCCESS;
un_PASS_SAR_CH_INTR_t unStat;
if (NULL != status)
{
unStat.u32Register = base->unINTR.u32Register;
status->chOverflow = (unStat.stcField.u1CH_OVERFLOW != 0ul) ? true : false;
status->chPulse = (unStat.stcField.u1CH_PULSE != 0ul) ? true : false;
status->chRange = (unStat.stcField.u1CH_RANGE != 0ul) ? true : false;
status->grpCancelled = (unStat.stcField.u1GRP_CANCELLED != 0ul) ? true : false;
status->grpDone = (unStat.stcField.u1GRP_DONE != 0ul) ? true : false;
status->grpOverflow = (unStat.stcField.u1GRP_OVERFLOW != 0ul) ? true : false;
}
else
{
ret = CY_ADC_BAD_PARAM;
}
return ret;
}
Code Listing 15 Cy_SysInt_SetSystemIrqVector() function
void Cy_SysInt_SetSystemIrqVector(cy_en_intr_t sysIntSrc, cy_systemIntr_Handler userIsr)
{
if (Cy_SysInt_SystemIrqUserTableRamPointer != NULL)
{
Cy_SysInt_SystemIrqUserTableRamPointer[sysIntSrc] = userIsr;
}
}
Code Listing 16 Cy_GPIO_Pin_Init() function
cy_en_gpio_status_t Cy_GPIO_Pin_Init(volatile stc_GPIO_PRT_t *base, uint32_t pinNum, const cy_stc_gpio_pin_config_t *config)
{
cy_en_gpio_status_t status = CY_GPIO_SUCCESS;
if((NULL != base) && (NULL != config))
{
Cy_GPIO_Write(base, pinNum, config->outVal);
Cy_GPIO_SetHSIOM(base, pinNum, config->hsiom);
Cy_GPIO_SetVtrip(base, pinNum, config->vtrip);
Cy_GPIO_SetSlewRate(base, pinNum, config->slewRate);
Cy_GPIO_SetDriveSel(base, pinNum, config->driveSel);
Cy_GPIO_SetDrivemode(base, pinNum, config->driveMode);
Cy_GPIO_SetInterruptEdge(base, pinNum, config->intEdge);
Cy_GPIO_ClearInterrupt(base, pinNum);
Cy_GPIO_SetInterruptMask(base, pinNum, config->intMask);
}
else
{
status = CY_GPIO_BAD_PARAM;
}
return(status);
}
Code Listing 17 Cy_Tcpwm_Pwm_Init() function
uint32_t Cy_Tcpwm_Pwm_Init(volatile stc_TCPWM_GRP_CNT_t* ptscTCPWM, cy_stc_tcpwm_pwm_config_t const* config)
{
uint32_t status = CY_RET_BAD_PARAM;
if((NULL != ptscTCPWM) && (NULL != config))
{
un_TCPWM_GRP_CNT_CTRL_t workCTRL = {.u32Register = 0ul};
workCTRL.stcField.u1ONE_SHOT = config->runMode;
workCTRL.stcField.u2UP_DOWN_MODE = config->countDirection;
workCTRL.stcField.u3MODE = config->pwmMode;
workCTRL.stcField.u1DBG_FREEZE_EN = config->debug_pause;
workCTRL.stcField.u1AUTO_RELOAD_CC0 = config->enableCompare0Swap;
workCTRL.stcField.u1AUTO_RELOAD_CC1 = config->enableCompare1Swap;
workCTRL.stcField.u1AUTO_RELOAD_PERIOD = config->enablePeriodSwap;
workCTRL.stcField.u1AUTO_RELOAD_LINE_SEL = config->enableLineSelSwap;
workCTRL.stcField.u1PWM_SYNC_KILL = config->killMode;
workCTRL.stcField.u1PWM_STOP_ON_KILL = (config->killMode>>1ul);
ptscTCPWM->unCTRL.u32Register = workCTRL.u32Register;
if(CY_TCPWM_COUNTER_COUNT_UP == config->runMode)
{
ptscTCPWM->unCOUNTER.u32Register = CY_TCPWM_CNT_UP_INIT_VAL;
}
else if(CY_TCPWM_COUNTER_COUNT_DOWN == config->runMode)
{
ptscTCPWM->unCOUNTER.u32Register = config->period;
}
else
{
ptscTCPWM->unCOUNTER.u32Register = CY_TCPWM_CNT_UP_DOWN_INIT_VAL;
}
ptscTCPWM->unCC0.u32Register = config->compare0;
ptscTCPWM->unCC1.u32Register = config->compare1;
ptscTCPWM->unPERIOD.u32Register = config->period;
un_TCPWM_GRP_CNT_TR_IN_SEL0_t workTR_IN_SEL0 = {.u32Register = 0ul};
workTR_IN_SEL0.stcField.u8CAPTURE0_SEL = config->switchInput;
workTR_IN_SEL0.stcField.u8RELOAD_SEL = config->reloadInput;
workTR_IN_SEL0.stcField.u8STOP_SEL = config->kill0Input;
workTR_IN_SEL0.stcField.u8COUNT_SEL = config->countInput;
ptscTCPWM->unTR_IN_SEL0.u32Register = workTR_IN_SEL0.u32Register;
un_TCPWM_GRP_CNT_TR_IN_SEL1_t workTR_IN_SEL1 = {.u32Register = 0ul};
workTR_IN_SEL1.stcField.u8CAPTURE1_SEL = config->kill1Input;
workTR_IN_SEL1.stcField.u8START_SEL = config->startInput;
ptscTCPWM->unTR_IN_SEL1.u32Register = workTR_IN_SEL1.u32Register;
un_TCPWM_GRP_CNT_TR_IN_EDGE_SEL_t workTR_IN_EDGE_SEL = {.u32Register = 0ul};
workTR_IN_EDGE_SEL.stcField.u2CAPTURE0_EDGE = config->switchInputMode;
workTR_IN_EDGE_SEL.stcField.u2CAPTURE1_EDGE = config->kill1InputMode;
workTR_IN_EDGE_SEL.stcField.u2RELOAD_EDGE = config->reloadInputMode;
workTR_IN_EDGE_SEL.stcField.u2START_EDGE = config->startInputMode;
workTR_IN_EDGE_SEL.stcField.u2STOP_EDGE = config->kill0InputMode;
workTR_IN_EDGE_SEL.stcField.u2COUNT_EDGE = config->countInputMode;
ptscTCPWM->unTR_IN_EDGE_SEL.u32Register = workTR_IN_EDGE_SEL.u32Register;
ptscTCPWM->unINTR_MASK.u32Register = config->interruptSources;
un_TCPWM_GRP_CNT_TR_PWM_CTRL_t workTR_PWM_CTRL = {.u32Register = 0ul};
workTR_PWM_CTRL.stcField.u2CC0_MATCH_MODE = config->Cc0MatchMode;
workTR_PWM_CTRL.stcField.u2CC1_MATCH_MODE = config->Cc1MatchMode;
workTR_PWM_CTRL.stcField.u2OVERFLOW_MODE = config->OverflowMode;
workTR_PWM_CTRL.stcField.u2UNDERFLOW_MODE = config->UnderflowMode;
ptscTCPWM->unTR_PWM_CTRL.u32Register = workTR_PWM_CTRL.u32Register;
un_TCPWM_GRP_CNT_DT_t workDT = {.u32Register = 0ul};
workDT.stcField.u16DT_LINE_COMPL_OUT = config->deadTimeComp;
workDT.stcField.u8DT_LINE_OUT_H = (config->deadTime>>8u);
if(config->pwmMode == CY_TCPWM_PWM_MODE_DEADTIME)
{
workDT.stcField.u8DT_LINE_OUT_L = config->deadTime;
}
else
{
workDT.stcField.u8DT_LINE_OUT_L = config->clockPrescaler;
}
ptscTCPWM->unDT.u32Register = workDT.u32Register;
status = CY_RET_SUCCESS;
}
return (status);
}
Code Listing 18 Cy_Tcpwm_Pwm_Enable() function
void Cy_Tcpwm_Pwm_Enable(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unCTRL.stcField.u1ENABLED = 0x1ul;
}
Code Listing 19 Cy_Tcpwm_TriggerStart() function
void Cy_Tcpwm_TriggerStart(volatile stc_TCPWM_GRP_CNT_t *ptscTCPWM)
{
ptscTCPWM->unTR_CMD.stcField.u1START = 0x1ul;
}
Code Listing 20 Cy_TrigMux_Connect1To1() function
cy_en_trigmux_status_t Cy_TrigMux_Connect1To1(uint32_t trig, uint32_t invert, en_trig_type_t trigType, uint32_t dbg_frz_en)
{
cy_en_trigmux_status_t retVal = CY_TRIGMUX_BAD_PARAM;
/* Validate output trigger */
if(Cy_TrigMux_IsOneToOne(trig) == false)
{
/* input trigger parameter is not One-To-One type */
return retVal;
}
/* Distill group and trigger No value from input trigger parameter */
uint8_t trigGroup = Cy_TrigMux_GetGroup(trig);
uint8_t trigNo = Cy_TrigMux_GetNo(trig);
/* Get a pointer to target trigger setting register */
volatile stc_PERI_TR_1TO1_GR_TR_CTL_field_t* pTR_CTL;
pTR_CTL = &(PERI->TR_1TO1_GR[trigGroup].unTR_CTL[trigNo].stcField);
/* Set input parameters to the register */
pTR_CTL->u1TR_SEL = true;
pTR_CTL->u1TR_INV = invert;
pTR_CTL->u1TR_EDGE = trigType;
pTR_CTL->u1DBG_FREEZE_EN = dbg_frz_en;
/* Return success status */
retVal = CY_TRIGMUX_SUCCESS;
return retVal;
}
A/D conversion ISR with hardware trigger
Figure 6 shows the example of ADC ISR with a hardware trigger. For details on CPU interrupt handing, see the architecture TRM mentioned in Related documents.
Figure 6. Example of ADC ISR with hardware trigger

Use case
See Section 3.1.1.
Configuration
Table 9 lists the parameters and Table 10 lists the functions of the configuration part of in SDL for ADC ISR with hardware trigger settings.
Table 9. Parameters for ADC ISR with hardware trigger
Parameters | Description | Value |
|---|---|---|
| Analog macro for the potentiometer on the TRAVEO™ T2G MCU baseboard | CY_ADC_POT_MACRO: PASS0_SAR0 |
| Conversion result buffer | - (Calculated Value) |
| Status result buffer | - (Calculated Value) |
| Index result | - (Calculated Value) |
| Interrupt source | - (Calculated Value) |
Table 10. Functions for ADC ISR with hardware trigger
Functions | Description | Value |
|---|---|---|
| Gets the conversion result and status | SAR Channel = BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL], Result = resultBuff[resultIdx], Status = statusBuff[resultIdx] |
| Clears the corresponding channel interrupt status | SAR Channel = BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL], Source = intrSource |
Sample code
See Code Listing 21 for sample code for initial configuration of ADC ISR with software trigger.
Code Listing 21 ADC ISR with software trigger
#define BB_POTI_ANALOG_MACRO CY_ADC_POT_MACRO
:
uint16_t resultBuff[16];
cy_stc_adc_ch_status_t statusBuff[16];
uint8_t resultIdx;
:
void AdcIntHandler(void)
{
cy_stc_adc_interrupt_source_t intrSource = { false };
:
{
/* Get the result(s) */ /* (1) Read A/D conversion data. See Code Listing 11. */
Cy_Adc_Channel_GetResult(&BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL], &resultBuff[resultIdx], &statusBuff[resultIdx]);
/* Display ADC result */
printf("\rADC result = %04d ", resultBuff[resultIdx]);
/* Increment result idx */
resultIdx = (resultIdx + 1) % (sizeof(resultBuff) / sizeof(resultBuff[0]));
/* Clear interrupt source */
Cy_Adc_Channel_ClearInterruptStatus(&BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL], &intrSource); */ (2) Clear and read A/D conversion flag. See Code Listing 21. */
:
}
else
{
// Unexpected interrupt
CY_ASSERT(false);
}
}
Group procedure
The SAR ADC has a function for consecutive conversion using multiple pins with one trigger. The pins and the order of conversions can be selected from any ports that can be configured as analog input.
ADC logical channels that are selected for consecutive conversion with one trigger are called ‘groups’.
A group trigger is defined by the first channel of the group, which has the trigger type set to ‘OFF’ (no hardware trigger), ‘TCPWM’, ‘Generic 0 to 4’, or ‘Continuous’.
If the “continue group with next channel” option is not set by the GROUP_END bit of the SARn_CHxTR_CTL register, the group will consist of only one channel. Otherwise, the group continues until the last channel in a row with its bit set to ‘last channel of a group’.
After the first channel of the group is triggered and converted, the second channel is automatically triggered and so on until the whole group is converted.
Figure 7 shows an example application that converts the voltage consecutively in the order of ADC[0]_10, ADC[0]_12 and ADC[0]_15 with one software trigger.
Ensure that you have set up the parameters as mentioned in Basic ADC global settings.
Figure 7. Example of group conversion connection

Use the information in the following sections and the example to implement this application.
Logical channel settings for group procedure
Figure 8 shows the example of logical channel setting for a group procedure in CYT2 series. In this example, the minimum value of the sample time is used. To find the proper sample time for your system, see the datasheet mentioned in Related documents.
Figure 8. Example of logical channel setting for group in CYT2 series

Although this example uses logical channels 0, 1, and 2, you can use any channel if those numbers are consecutive.
Use case
The following use case is an example of logical channel setting for group.
- ADC trigger selection: OFF
- Channel priority: 0 (highest)
- Channel pre-emption type: Finish resume
- Analog input, channel group and interrupt
Channel | Analog input | Channel group | Interrupt |
|---|---|---|---|
CH0 | ADC[0]_10 | Continue group with next channel | Disable |
CH1 | ADC[0]_12 | Continue group with next channel | Disable |
CH2 | ADC[0]_15 | Last channel of a group | Enable group done interrupt |
- ADC done level: Pulse
- External analog MUX: 0, Enable
- Pre-conditioning Mode: OFF
- Overlap diagnostics mode: OFF
- Calibration value select: Regular
- Post processing mode: None
- Result alignment: Right
- Sign extension: Unsigned
- Averaging count: 0
- Shift right: 0
- Mask group: Not done/Not cancelled/Not overflow
- Mask channel: Not range/Not pulse/Not overflow
Configuration
Table 11 lists the parameters and Table 12 lists the functions of logical channel setting for group in CYT2 series.
Table 11. Parameters for logical channel setting for group in CYT2
series
Parameters | Description | Value |
|---|---|---|
| ADC logical channel | 0ul |
| ADC channel number in the group | 3ul |
| First channel of ADC group | ADC_LOGICAL_CHANNEL |
| Last channel of ADC group | ADC_GROUP_FIRST_CHANNEL + ADC_GROUP_NUMBER_OF_CHANNELS - 1ul |
| Analog macro for the potentiometer on the TRAVEO™ T2G baseboard | CY_ADC_POT_MACRO: PASS0_SAR0 |
| Trigger OFF | 0ul (See Table 3) |
| Channel priority | 0ul |
| Pre-emption type | 3ul (See Table 3) |
| Is group end? | CH0: false, CH1: false, CH2: true |
| Done level | 0ul (See Table 3) |
| Pin address | BB_POTI_ANALOG_INPUT_NO |
| Port address | 0ul (See Table 3) |
| External MUX select | 0ul |
| Enable external MUX | true |
| Pre-condition mode | 0ul (See Table 3) |
| Overlap diagnostics mode | 0ul (See Table 3) |
| Sample time | samplingCycle (Calculated Value) |
| Calibration value select | 0ul (See Table 3) |
| Post processing mode | 0ul (See Table 3) |
| Result alignment | 0ul (See Table 3) |
| Sign extension | 0ul (See Table 3) |
| Average count | 0ul |
| Right shift | 0ul |
| Range detection mode | 2ul (See Table 3) |
| Range detection low threshold | 0x0000ul |
| Range detection high threshold | 0x0FFFul |
| Mask group done | CH0: false, CH1: false, CH2: true |
| Mask group cancelled | false |
| Mask group overflow | false |
| Mask channel range | false |
| Mask channel pulse | false |
| Mask channel overflow | false |
Table 12. Functions for logical channel setting for group in CYT2 series
Functions | Description | Value |
|---|---|---|
| Initializes the ADC channel | PASS SARchannel = &BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL] ADCchannel Configure = adcChannelConfig |
| Initializes the referenced system interrupt by setting the interrupt vector | Config = irq_cfg |
| Enables the corresponding channel | SARchannel = PASS_SAR_CH |
| Issues a software start trigger | PASS SARchannel = &BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL] |
Sample code
See Code Listing 22 for sample code for initial configuration of logical channel settings for group procedure.
Code Listing 22 Logical channel settings for group procedure
#define BB_POTI_ANALOG_PCLK CY_ADC_POT_PCLK
#define BB_POTI_ANALOG_INPUT_NO ((cy_en_adc_pin_address_t)CY_ADC_POT_IN_NO)
:
#define ADC_GROUP_FIRST_CHANNEL ADC_LOGICAL_CHANNEL
#define ADC_GROUP_LAST_CHANNEL (ADC_GROUP_FIRST_CHANNEL + ADC_GROUP_NUMBER_OF_CHANNELS - 1u)
uint16_t resultBuff[ADC_GROUP_NUMBER_OF_CHANNELS][16];
cy_stc_adc_ch_status_t statusBuff[ADC_GROUP_NUMBER_OF_CHANNELS][16];
uint8_t resultIdx;
:
int main(void)
{
:
__enable_irq(); /* Enable global interrupts. */
/* Initialize ADC */
{
:
cy_stc_adc_config_t adcConfig = /* ADC Configuration. */
{
.preconditionTime = 0ul,
.powerupTime = 0ul,
.enableIdlePowerDown = false,
.msbStretchMode = CY_ADC_MSB_STRETCH_MODE_2CYCLE,
.enableHalfLsbConv = 0ul,
.sarMuxEnable = true,
.adcEnable = true,
.sarIpEnable = true,
};
cy_stc_adc_channel_config_t adcChannelConfig =
{
.triggerSelection = CY_ADC_TRIGGER_OFF, /* (1) Trigger Type Setting */
.channelPriority = 0ul,
.preenptionType = CY_ADC_PREEMPTION_FINISH_RESUME, /* Preemption Type Setting */
.isGroupEnd = false, /* Group End Setting */
.doneLevel = CY_ADC_DONE_LEVEL_PULSE, /* Level or Pulse Selection */
.pinAddress = BB_POTI_ANALOG_INPUT_NO, /* (2) Analog Input Setting, Sample Time Setting */
.portAddress = CY_ADC_PORT_ADDRESS_SARMUX0, /* (2) Analog Input Setting, Sample Time Setting */
.extMuxSelect = 0ul, /* (2) Analog Input Setting, Sample Time Setting */
.extMuxEnable = true, /* (2) Analog Input Setting, Sample Time Setting */
.preconditionMode = CY_ADC_PRECONDITION_MODE_OFF, /* (2) Analog Input Setting, Sample Time Setting */
.overlapDiagMode = CY_ADC_OVERLAP_DIAG_MODE_OFF, /* (2) Analog Input Setting, Sample Time Setting */
.sampleTime = samplingCycle, /* (2) Analog Input Setting, Sample Time Setting */
.calibrationValueSelect = CY_ADC_CALIBRATION_VALUE_REGULAR, /* (2) Analog Input Setting, Sample Time Setting */
.postProcessingMode = CY_ADC_POST_PROCESSING_MODE_NONE, /* (2) Analog Input Setting, Sample Time Setting */
.resultAlignment = CY_ADC_RESULT_ALIGNMENT_RIGHT, /* (2) Analog Input Setting, Sample Time Setting */
.signExtention = CY_ADC_SIGN_EXTENTION_UNSIGNED, /* (2) Analog Input Setting, Sample Time Setting */
.averageCount = 0u, /* (2) Analog Input Setting, Sample Time Setting */
.rightShift = 0u, /* (2) Analog Input Setting, Sample Time Setting */
.rangeDetectionMode = CY_ADC_RANGE_DETECTION_MODE_INSIDE_RANGE, /* (2) Analog Input Setting, Sample Time Setting */
.rangeDetectionLoThreshold = 0x0000ul, /* (2) Analog Input Setting, Sample Time Setting */
.rangeDetectionHiThreshold = 0x0FFFul, /* (2) Analog Input Setting, Sample Time Setting */
.mask.grpDone = false, /* (3) Interrupt Mask Setting */
.mask.grpCancelled = false, /* (3) Interrupt Mask Setting */
.mask.grpOverflow = false, /* (3) Interrupt Mask Setting */
.mask.chRange = false, /* (3) Interrupt Mask Setting */
.mask.chPulse = false, /* (3) Interrupt Mask Setting */
.mask.chOverflow = false, /* (3) Interrupt Mask Setting */
};
Cy_Adc_Init(BB_POTI_ANALOG_MACRO, &adcConfig); /* ADC Configuration setting. See Code Listing 2. */
adcChannelConfig.isGroupEnd = false;
adcChannelConfig.mask.grpDone = false;
for (uint8_t ch = ADC_GROUP_FIRST_CHANNEL; ch < (ADC_GROUP_FIRST_CHANNEL + ADC_GROUP_NUMBER_OF_CHANNELS); ch++)
{
uint8_t i = ch - ADC_GROUP_FIRST_CHANNEL; // i is 0-based for array indexing
if(ch == ADC_GROUP_LAST_CHANNEL)
{
adcChannelConfig.isGroupEnd = true;
adcChannelConfig.mask.grpDone = true;
}
adcChannelConfig.pinAddress = aenAnalogInput[i];
Cy_Adc_Channel_Init(&BB_POTI_ANALOG_MACRO->CH[ch], &adcChannelConfig); /* ADC Channel Initialize. See Code Listing 5. */
}
:
Cy_SysInt_InitIRQ(&irq_cfg); /* (4) Initialize Interrupt Request. See Code Listing 7. */
:
/* Enable ADC ch. */
for (uint8_t ch = ADC_GROUP_FIRST_CHANNEL; ch < (ADC_GROUP_FIRST_CHANNEL + ADC_GROUP_NUMBER_OF_CHANNELS); ch++)
{
Cy_Adc_Channel_Enable(&CY_ADC_POT_MACRO->CH[ch]); /* (5) Enable ADC Channel. See Code Listing 8. */
}
:
/* Issue SW trigger */
Cy_Adc_Channel_SoftwareTrigger(&CY_ADC_POT_MACRO->CH[ADC_GROUP_FIRST_CHANNEL]); /* (6) Software Trigger Setting. See Code Listing 9. */
:
for(;;)
{
}
}
A/D conversion ISR for group
Figure 9 shows the example of ADC ISR for the group. For details on CPU interrupt handling, see the architecture TRM mentioned in the Related documents.
Figure 9. Example of ADC ISR for group

Use case
See Section 4.1.1.
Configuration
Table 13 lists the parameters and Table 14 lists the functions of the configuration part of in SDL for ADC ISR for group settings.
Table 13. Parameters for ADC ISR for group settings
Parameters | Description | Value |
|---|---|---|
| Conversion result buffer | - (Calculated Value) |
| Status result buffer | - (Calculated Value) |
| Index result | - (Calculated Value) |
| Interrupt source | - (Calculated Value) |
Table 14. Functions for ADC ISR for group settings
Functions | Description | Value |
|---|---|---|
| Gets conversion result and status | SAR Channel = BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL], Result = resultBuff[resultIdx], Status = statusBuff[resultIdx] |
| Clears the corresponding channel interrupt status | SAR Channel = BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL], Source = intrSource |
| Issues a software start trigger | SAR Channel = BB_POTI_ANALOG_MACRO->CH[ADC_LOGICAL_CHANNEL] |
Sample code
See Code Listing 23 for sample code for initial configuration of ADC ISR for group settings.
Code Listing 23 ADC ISR for group settings
#define BB_POTI_ANALOG_MACRO CY_ADC_POT_MACRO
:
#define ADC_GROUP_FIRST_CHANNEL ADC_LOGICAL_CHANNEL
#define ADC_GROUP_LAST_CHANNEL (ADC_GROUP_FIRST_CHANNEL + ADC_GROUP_NUMBER_OF_CHANNELS - 1u)
uint16_t resultBuff[ADC_GROUP_NUMBER_OF_CHANNELS][16];
cy_stc_adc_ch_status_t statusBuff[ADC_GROUP_NUMBER_OF_CHANNELS][16];
uint8_t resultIdx;
void AdcIntHandler(void)
{
cy_stc_adc_interrupt_source_t intrSource = { false };
:
{
:
/* Get the result(s) */
for(uint8_t ch = ADC_GROUP_FIRST_CHANNEL; ch < (ADC_GROUP_FIRST_CHANNEL + ADC_GROUP_NUMBER_OF_CHANNELS); ch++)
{
uint8_t i = ch - ADC_GROUP_FIRST_CHANNEL; // i is 0-based for array indexing
Cy_Adc_Channel_GetResult(&BB_POTI_ANALOG_MACRO->CH[ch], &resultBuff[i][resultIdx], &statusBuff[i][resultIdx]); /* (1) Read A/D conversion data. See Code Listing 11. */
printf("AN%d = %04d, ", aenAnalogInput[i], resultBuff[i][resultIdx]);
}
/* Increment result idx */
resultIdx = (resultIdx + 1ul) % (sizeof(resultBuff[0]) / sizeof(resultBuff[0][0]));
/* Clear interrupt source(s) (Only last channel is required) */
Cy_Adc_Channel_ClearInterruptStatus(&BB_POTI_ANALOG_MACRO->CH[ADC_GROUP_LAST_CHANNEL], &intrSource); /* (2) Clear and read A/D conversion flag. See Code Listing 12. */
/* Trigger next conversion */
Cy_Adc_Channel_SoftwareTrigger(&BB_POTI_ANALOG_MACRO->CH[ADC_GROUP_FIRST_CHANNEL]); /* (3) Software Trigger Setting. See Code Listing 9. */
}
else
{
// Unexpected interrupt
CY_ASSERT(false);
}
}
Averaging procedure
Averaging is fully configured per channel by SARn_CHx_POST_CTL register.
The number of samples averaged is up to 256.
This section shows an example application that converts voltage values given to the ADC[0]_0 at the MCU to digital averaging values.
The physical setting of this application is the same as shown in Figure 1.
Ensure that you have configured the settings as described in the Basic ADC global settings, Use case, and A/D conversion ISR with software trigger sections.
Use the information in the following sections and the example to implement this application.
Averaging settings
Figure 10 shows the example of averaging setting. The ADC result of the specified averaging count is accumulated, and it is shifted to the right by specifying right shift bit. Then, it is stored in the result register. For true averaging, the averaging count should be a power of 2 and the right shift should be set to the corresponding value. For an averaging count that is not a power of 2, the right shift can only approximate the required divide. In this case, if a true averaging result is required, the software will need to do a divide.
Figure 10. Example of averaging setting

Use case
The following use case is an example of averaging setting.
- Post processing mode: Averaging
- Averaging count: 1 + 1 times
- Right shift: 1
- Other use case items are the same as Section 2.3.1.
Configuration
Table 15 lists the parameters and Table 16 lists the functions of the configuration part of in SDL for averaging settings.
Table 15. Parameters for averaging
Parameters | Description | Value |
|---|---|---|
| Analog macro for the potentiometer on TRAVEO™ T2G baseboard | CY_ADC_POT_MACRO: PASS0_SAR0 |
| Trigger OFF | 0ul (See Table 3) |
| Channel priority | 0ul |
| Pre-emption type | 3ul (See Table 3) |
| Is group end? | true |
| Done level | 0ul (See Table 3) |
| Pin address | BB_POTI_ANALOG_INPUT_NO |
| Port address | 0ul (See Table 3) |
| External MUX select | 0ul |
| Enables external MUX | true |
| Pre-condition mode | 0ul (See Table 3) |
| Overlap diagnostics mode | 0ul (See Table 3) |
| Sample time | 0ul |
| Calibration value select | 0ul (See Table 3) |
| Post processing mode | 1ul (See Table 3) |
| Result alignment | 0ul (See Table 3) |
| Sign extension | 0ul (See Table 3) |
| Average count | 1ul |
| Right shift | 1ul |
| Range detection mode | 0ul (See Table 3) |
| Range detection low threshold | 0x0000ul |
| Range detection high threshold | 0x0FFFul |
| Mask group done | true |
| Mask group cancelled | false |
| Mask group overflow | false |
| Mask channel range | false |
| Mask channel pulse | false |
| Mask channel overflow | false |