MTB CAT1 Peripheral driver library
SAR2 (Analog to Digital Converter (ADC))

General Description

The SAR2 driver provides an API to configure the SAR2 ADC.

The SAR2 has up to 4 ADCs and up to 32 channels for each ADC module. About actual number of supported modules and channels, refer to the technical reference manual (TRM) and device datasheet.

Configuration Considerations

Typical usage:

Note
It is not recommended to set the triggerSelection structure member of the cy_stc_sar2_channel_config_t to CY_SAR2_TRIGGER_CONTINUOUS if cy_en_sar2_preemption_type_t is set to CY_SAR2_PREEMPTION_ABORT_CANCEL. It may work to the effect that the channel or channel group will not be able to complete without advanced priority tuning.
Note
If you use an interrupt for ADC, create an interrupt handler and register it by using the sysint module. In the handler, you can check which interrupt is occurred by Cy_SAR2_Channel_GetInterruptStatusMasked and can get the conversion result by Cy_SAR2_Channel_GetResult. If you do not use the interrupt, you can poll the conversion status by Cy_SAR2_Channel_GetInterruptStatus. For both of polling and interrupt, clear the interrupt flags by Cy_SAR2_Channel_ClearInterrupt after handling data.
Note
SAR2 block can operate in Active or Sleep mode only.

Configuration Example

First step would be to configure clock:

/* Scenario: CLH_HF2 has been configured to output 196 MHz.
* Use one of the PeriClk dividers with a divider value of 50 to get a 3.92 Mhz SAR clock. */
/* Assign divider number 0 of the the 8-bit dividers to the SAR2, block 0. */
/* Disable assigned divider. */
Cy_SysClk_PeriPclkDisableDivider((1U << PERI_PCLK_GR_NUM_Pos), CY_SYSCLK_DIV_8_BIT, 0U);
/* Divide the PeriClk by 50, which is a input value of 49. */
Cy_SysClk_PeriPclkSetDivider((1U << PERI_PCLK_GR_NUM_Pos), CY_SYSCLK_DIV_8_BIT, 0U, 49U);
/* Enable the divider. */
Cy_SysClk_PeriPclkEnableDivider((1U << PERI_PCLK_GR_NUM_Pos), CY_SYSCLK_DIV_8_BIT, 0U);

Group of two SAR2 ADC channels are configured, one for bandgap voltage and one for the AN0 analogue input:

/* Scenario: SAR2 ADC configuration */
cy_stc_sar2_channel_config_t channel_vbg_config =
{
.channelHwEnable = true,
.triggerSelection = CY_SAR2_TRIGGER_OFF,
.channelPriority = 0U,
.isGroupEnd = false,
.pinAddress = CY_SAR2_PIN_ADDRESS_VBG,
.extMuxEnable = true,
.extMuxSelect = 0U,
.preconditionMode = CY_SAR2_PRECONDITION_MODE_OFF,
.overlapDiagMode = CY_SAR2_OVERLAP_DIAG_MODE_OFF,
.sampleTime = 120U,
.postProcessingMode = CY_SAR2_POST_PROCESSING_MODE_NONE,
.resultAlignment = CY_SAR2_RESULT_ALIGNMENT_RIGHT,
.averageCount = 1U,
.rightShift = 0U,
.rangeDetectionLoThreshold = 0U,
.rangeDetectionHiThreshold = 65535U,
};
cy_stc_sar2_channel_config_t channel_an0_config =
{
.channelHwEnable = true,
.triggerSelection = CY_SAR2_TRIGGER_OFF,
.channelPriority = 0U,
.isGroupEnd = true,
.pinAddress = CY_SAR2_PIN_ADDRESS_AN0,
.extMuxEnable = true,
.extMuxSelect = 0U,
.preconditionMode = CY_SAR2_PRECONDITION_MODE_OFF,
.overlapDiagMode = CY_SAR2_OVERLAP_DIAG_MODE_OFF,
.sampleTime = 120U,
.postProcessingMode = CY_SAR2_POST_PROCESSING_MODE_NONE,
.resultAlignment = CY_SAR2_RESULT_ALIGNMENT_RIGHT,
.averageCount = 1U,
.rightShift = 0U,
.rangeDetectionLoThreshold = 0U,
.rangeDetectionHiThreshold = 65535U,
};
cy_stc_sar2_config_t sar2_config =
{
.powerupTime = 0U,
.enableIdlePowerDown = false,
.enableHalfLsbConv = false,
.sarMuxEnable = true,
.adcEnable = true,
.sarIpEnable = true,
.channelConfig = {&channel_vbg_config, &channel_an0_config,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, },
};
/* We've created group of two channels. By triggering the first one - whole group will be
* executed. */

Initialization

/* Scenario: SAR2 ADC initialization */
#define CH_VBG (0u)
#define CH_AN0 (1u)
/* Initialize the SAR2 module */
Cy_SAR2_Init(PASS0_SAR0, &sar2_config);
/* Set ePASS MMIO reference buffer mode for bangap voltage */

Obtaining results in counts

/* Scenario: Obtaining conversion results in counts */
uint16_t resultVBG;
uint16_t resultAN0;
/* Issue software start trigger */
Cy_SAR2_Channel_SoftwareTrigger(PASS0_SAR0, CH_VBG);
/* Wait for conversion to finish */
/* Get conversion results in counts, do not obtain or analyze status here */
resultVBG = Cy_SAR2_Channel_GetResult(PASS0_SAR0, CH_VBG, NULL);
resultAN0 = Cy_SAR2_Channel_GetResult(PASS0_SAR0, CH_AN0, NULL);
/* Each channel results are stored in ADC counts at this point. */
/* Clear interrupt source */

Calculating results in V, mV or uV

/* Scenario: Calculating V, mV and uV from counts. */
float32_t volts;
float32_t mVolts;
float32_t uVolts;
/* Calculate conversion results in volts */
volts = (resultAN0 * 0.9f) / resultVBG;
mVolts = (resultAN0 * 900.0f) / resultVBG;
uVolts = (resultAN0 * 900000.0f) / resultVBG;

Die temperature

/* Scenario: die temperature measurement */
uint16_t resultTemp;
double dieTemperature;
/* Reconfigure the CH_AN0 to measure the temperature sensor */
channel_an0_config.pinAddress = CY_SAR2_PIN_ADDRESS_VTEMP;
/* Averaging is very useful for the temperature measurements */
channel_an0_config.averageCount = 16U; /* Accumulate 16 samples */
channel_an0_config.rightShift = 4U; /* Divide the result by 16 */
/* Issue software start trigger */
Cy_SAR2_Channel_SoftwareTrigger(PASS0_SAR0, CH_VBG);
/* Wait for conversion to finish */
/* Get conversion results in counts, do not obtain or analyze status here */
resultVBG = Cy_SAR2_Channel_GetResult(PASS0_SAR0, CH_VBG, NULL); /* Measure the VBG value */
resultTemp = Cy_SAR2_Channel_GetResult(PASS0_SAR0, CH_AN0, NULL); /* Measure the temperature sensor value */
/* Assume the VDDA voltage is 3.3V */
dieTemperature = Cy_SAR2_CalculateDieTemperature(CY_SAR2_VDDA_2_7V_TO_4_5V, resultTemp, resultVBG);

Once done, in the variable, returned by the Cy_SAR2_CalculateDieTemperature function will contain the die temperature value in Celsius degrees.

The accuracy can be increased by executing the calibration procedure (see Calibration procedure section) before doing the conversion.

In the function call, the first argument is the enumeration value, representing the VDDA value range supplied to this particular chip being used, see cy_en_sar2_vdda_range_t.

Channel grouping

The SAR2 driver supports the channel grouping. Each channel can be either in an individual group or in a group of 2 or more channels. By default, the hardware will execute the next channel if it exists and is in the Enabled state if the current channel does not have the flag 'Group End' set. You can set triggers to start either the first channel or any channel of the group to execute all the next channels.

More Information

Refer to the technical reference manual (TRM) and the device datasheet.

Changelog

VersionChangesReason for Change
1.1 Adding support for devices with up to 3 SAR slices.
1.0 Initial version

API Reference

 Macros
 
 Functions
 
 Data structures
 
 Enumerated Types
 
 Calibration procedure