High level interface for interacting with the analog to digital converter (ADC).
Each ADC instance supports one or more selectable channels, each of which can perform conversions on a different pin. See the device datasheet for details about which pins support ADC conversion.
Both single-ended and differential channels are supported. The values returned by the read API are relative to the ADC's voltage range, which is device specific. See the BSP documentation for details.
Call cyhal_adc_init to initialize an ADC instance by providing the ADC object (obj), input pin (pin) and clock (clk).
The input pin argument is just to signify which ADC instance to initialize. It does not actually reserve the pin or create an ADC channel for it. The clock parameter can be left NULL to use an available clock resource with a default frequency.
Use cyhal_adc_channel_init_diff to initialize one or more channels associated with that instance.
Use cyhal_adc_read for reading the results.
See Snippet 1: Simple ADC initialization and reading conversion result.
The following snippet initializes an ADC and one channel. One ADC conversion result is returned corresponding to the input at the specified pin.
The following snippet initializes an ADC with one single-ended channel and one differential channel
The following snippet illustrates how to asynchronously read multiple scans of multiple channels.
This snippet shows how to run the ADC in continuous mode and process results as each scan completes.
API Reference | |
ADC HAL Results | |
ADC specific return codes. | |
Data Structures | |
struct | cyhal_adc_config_t |
ADC Configuration. More... | |
struct | cyhal_adc_channel_config_t |
ADC Channel Configuration. More... | |
Macros | |
#define | CYHAL_ADC_BITS 16 |
Number of bits populated with meaningful data by each ADC sample. | |
#define | CYHAL_ADC_MAX_VALUE ((1 << CYHAL_ADC_BITS) - 1) |
Maximum value that the ADC can return. | |
#define | CYHAL_ADC_AVG_MODE_AVERAGE (1u << 0) |
Perform standard averaging. More... | |
#define | CYHAL_ADC_AVG_MODE_ACCUMULATE (1u << 1) |
Accumulate samples as in CYHAL_ADC_AVG_MODE_AVERAGE, but do not divide by the number of samples. | |
#define | CYHAL_ADC_AVG_MODE_MAX_SHIFT (1u) |
Average mode flag position indices shifted by greater than this are implementation specific. More... | |
#define | CYHAL_ADC_VNEG CYHAL_NC_PIN_VALUE |
Selects the default connection for the inverting input to achieve a single-ended channel. More... | |
Typedefs | |
typedef void(* | cyhal_adc_event_callback_t) (void *callback_arg, cyhal_adc_event_t event) |
Handler for ADC event callbacks. | |
Enumerations | |
enum | cyhal_adc_vref_t { CYHAL_ADC_REF_INTERNAL, CYHAL_ADC_REF_EXTERNAL, CYHAL_ADC_REF_VDDA, CYHAL_ADC_REF_VDDA_DIV_2 } |
Possible selections for ADC reference. More... | |
enum | cyhal_adc_vneg_t { CYHAL_ADC_VNEG_VSSA, CYHAL_ADC_VNEG_VREF } |
Vminus selection for single-ended channels. More... | |
enum | cyhal_adc_event_t { CYHAL_ADC_EOS = 1u, CYHAL_ADC_ASYNC_READ_COMPLETE = 2u } |
ADC events. More... | |
Functions | |
cy_rslt_t | cyhal_adc_init (cyhal_adc_t *obj, cyhal_gpio_t pin, const cyhal_clock_t *clk) |
Initialize ADC peripheral. More... | |
void | cyhal_adc_free (cyhal_adc_t *obj) |
Uninitialize the ADC peripheral and cyhal_adc_t object. More... | |
cy_rslt_t | cyhal_adc_configure (cyhal_adc_t *obj, const cyhal_adc_config_t *config) |
Update the ADC configuration. More... | |
cy_rslt_t | cyhal_adc_set_power (cyhal_adc_t *obj, cyhal_power_level_t power) |
Changes the current operating power level of the ADC. More... | |
cy_rslt_t | cyhal_adc_set_sample_rate (cyhal_adc_t *obj, uint32_t desired_sample_rate_hz, uint32_t *achieved_sample_rate_hz) |
Configure the number of samples per second. More... | |
cy_rslt_t | cyhal_adc_channel_init_diff (cyhal_adc_channel_t *obj, cyhal_adc_t *adc, cyhal_gpio_t vplus, cyhal_gpio_t vminus, const cyhal_adc_channel_config_t *cfg) |
Initialize a differential ADC channel. More... | |
cy_rslt_t | cyhal_adc_channel_configure (cyhal_adc_channel_t *obj, const cyhal_adc_channel_config_t *config) |
Update the ADC channel configuration. More... | |
void | cyhal_adc_channel_free (cyhal_adc_channel_t *obj) |
Uninitialize the ADC channel and cyhal_adc_channel_t object. More... | |
uint16_t | cyhal_adc_read_u16 (const cyhal_adc_channel_t *obj) |
Read the value from the ADC pin, represented as an unsigned 16bit value where 0x0000 represents the minimum value in the ADC's range, and 0xFFFF represents the maximum value in the ADC's range. More... | |
int32_t | cyhal_adc_read (const cyhal_adc_channel_t *obj) |
Read the value from ADC pin, represented as a 32-bit signed, right-aligned value. More... | |
int32_t | cyhal_adc_read_uv (const cyhal_adc_channel_t *obj) |
Read the value from ADC pin, in microvolts. More... | |
cy_rslt_t | cyhal_adc_read_async (cyhal_adc_t *obj, size_t num_scan, int32_t *result_list) |
Scan the specified ADC channels in the background and copy the results into the array pointed to by result_list . More... | |
cy_rslt_t | cyhal_adc_read_async_uv (cyhal_adc_t *obj, size_t num_scan, int32_t *result_list) |
Scan the specified ADC channels in the background and copy the conversion results in microvolts into the array pointed to by result_list . More... | |
cy_rslt_t | cyhal_adc_set_async_mode (cyhal_adc_t *obj, cyhal_async_mode_t mode, uint8_t dma_priority) |
Set the mechanism that is used to perform ADC asynchronous transfers. More... | |
void | cyhal_adc_register_callback (cyhal_adc_t *obj, cyhal_adc_event_callback_t callback, void *callback_arg) |
Register an ADC callback handler. More... | |
void | cyhal_adc_enable_event (cyhal_adc_t *obj, cyhal_adc_event_t event, uint8_t intr_priority, bool enable) |
Configure ADC events. More... | |
struct cyhal_adc_config_t |
Data Fields | ||
---|---|---|
bool | continuous_scanning |
Whether the ADC samples continuously (true) or only on demand (false). When configured to true, the ADC will immediately begin scanning all configured channels. When configured to false, the ADC will stop continuous scanning at the completion of the current scan |
uint8_t | resolution |
ADC resolution. See the implementation specific documentation for supported values |
uint16_t | average_count |
The number of samples that should be averaged together to obtain a result. A value of 1 disables averaging. |
uint32_t | average_mode_flags |
Flags to control the behavior of the averaging functionality when average_count is greater than 1. This field contains zero or more flags that are OR'd together. All implementations define CYHAL_ADC_AVG_MODE_AVERAGE and CYHAL_ADC_AVG_MODE_ACCUMULATE (though some may not support both modes). Some implementations may define other flags to control additional aspects of the averaging functionality; see the implementation-specific documentation for details. |
uint32_t | ext_vref_mv |
The external voltage reference value, in millivolts. If vref is set to CYHAL_ADC_REF_EXTERNAL, this must be nonzero. If vref is set to anything other than CYHAL_ADC_REF_EXTERNAL, this must be zero. |
cyhal_adc_vneg_t | vneg | Vminus selection for single-ended channels. |
cyhal_adc_vref_t | vref | ADC voltage reference. |
cyhal_gpio_t | ext_vref |
The GPIO that should be used for the external reference. If CYHAL_ADC_REF_EXTERNAL is selected and the current target uses a GPIO for ADC ext_vref (see the BSP documentation), this must not be NC. If the current target uses a dedicated pin (not a GPIO) for ADC ext_vref, or if any other reference is selected, this must be NC. |
bool | is_bypassed |
Whether an external bypass capacitor should be used. Depending on the platform this may be required to reduce noise at sufficiently high sample rates. See the implementation specific documentation for details. |
cyhal_gpio_t | bypass_pin |
The GPIO pin that should be used for the bypass capacitor. If |
struct cyhal_adc_channel_config_t |
Data Fields | ||
---|---|---|
bool | enabled | Whether this channel should be sampled when the ADC performs a scan. |
bool | enable_averaging |
Enable or disable averaging for this channel. All other aspects of the averging functionality are configured in cyhal_adc_config_t |
uint32_t | min_acquisition_ns |
Minimum time that this channel should be sampled, in nanoseconds. The actual time may be greater than this depending on hardware limitations, the sample rate, and the configuration of other channels.
|
#define CYHAL_ADC_AVG_MODE_AVERAGE (1u << 0) |
Perform standard averaging.
Divide the accumulated value by the number of samples.
#define CYHAL_ADC_AVG_MODE_MAX_SHIFT (1u) |
Average mode flag position indices shifted by greater than this are implementation specific.
The value of this macro is subject to change between HAL versions.
#define CYHAL_ADC_VNEG CYHAL_NC_PIN_VALUE |
Selects the default connection for the inverting input to achieve a single-ended channel.
This connection is controlled by the vneg
member of cyhal_adc_config_t.
enum cyhal_adc_vref_t |
Possible selections for ADC reference.
enum cyhal_adc_vneg_t |
Vminus selection for single-ended channels.
Enumerator | |
---|---|
CYHAL_ADC_VNEG_VSSA | Connect vminus to ground. |
CYHAL_ADC_VNEG_VREF | Connect vminus to the selected vref (see cyhal_adc_vref_t) |
enum cyhal_adc_event_t |
cy_rslt_t cyhal_adc_init | ( | cyhal_adc_t * | obj, |
cyhal_gpio_t | pin, | ||
const cyhal_clock_t * | clk | ||
) |
Initialize ADC peripheral.
The ADC will be initialized with the following default configuration:
To change the configuration, see cyhal_adc_configure
[out] | obj | Pointer to an ADC object. The caller must allocate the memory for this object but the init function will initialize its contents. |
[in] | pin | A pin corresponding to the ADC block to initialize Note: This pin is not reserved, it is just used to identify which ADC block to allocate. If multiple channels will be allocated for a single ADC instance, only one pin should be passed here; it does not matter which one. After calling this function once, call cyhal_adc_channel_init_diff once for each pin whose value should be measured. |
[in] | clk | The clock to use can be shared, if not provided a new clock will be allocated |
void cyhal_adc_free | ( | cyhal_adc_t * | obj | ) |
Uninitialize the ADC peripheral and cyhal_adc_t object.
[in,out] | obj | The ADC object |
cy_rslt_t cyhal_adc_configure | ( | cyhal_adc_t * | obj, |
const cyhal_adc_config_t * | config | ||
) |
Update the ADC configuration.
[in] | obj | The ADC object |
[in] | config | The configuration to apply |
cy_rslt_t cyhal_adc_set_power | ( | cyhal_adc_t * | obj, |
cyhal_power_level_t | power | ||
) |
Changes the current operating power level of the ADC.
If the power level is set to CYHAL_POWER_LEVEL_OFF, the ADC will be powered-off but it will retain its configuration, so it is not necessary to reconfigure it when changing the power level from CYHAL_POWER_LEVEL_OFF to any other value.
[in] | obj | ADC object |
[in] | power | The power level to set |
cy_rslt_t cyhal_adc_set_sample_rate | ( | cyhal_adc_t * | obj, |
uint32_t | desired_sample_rate_hz, | ||
uint32_t * | achieved_sample_rate_hz | ||
) |
Configure the number of samples per second.
This is the number of times each enabled channel is sampled per second. The total number of samples performed by the ADC hardware per second is equal to sample_rate_hz / num_channels_enabled
. Depending on the system clock configuration or limitations of the underlying hardware, it may not be possible to achieve precisely the desired sample rate. The achived_sample_rate_hz
parameter will be updated to indicate the sample rate that was achived.
achieved_sample_rate_hz
value is only valid while the configuration of the ADC and its channels remains umodified. If cyhal_adc_configure, cyhal_adc_channel_init_diff, cyhal_adc_channel_configure, or cyhal_adc_channel_free is called, it is necessary to call this function again in order to update the sample rate. Therefore, it is recommended to call this function after the ADC and all channels have been configured.[in] | obj | The ADC object to configure |
[in] | desired_sample_rate_hz | The desired sample rate, in hertz |
[out] | achieved_sample_rate_hz | The achieved sample rate, in hertz |
cy_rslt_t cyhal_adc_channel_init_diff | ( | cyhal_adc_channel_t * | obj, |
cyhal_adc_t * | adc, | ||
cyhal_gpio_t | vplus, | ||
cyhal_gpio_t | vminus, | ||
const cyhal_adc_channel_config_t * | cfg | ||
) |
Initialize a differential ADC channel.
Configures the pin used by ADC.
[out] | obj | The ADC channel object to initialize |
[in] | adc | The ADC for which the channel should be initialized |
[in] | vplus | Non-inverting input |
[in] | vminus | Inverting input. For a single ended channel, use CYHAL_ADC_VNEG. |
[in] | cfg | The ADC channel configuration |
cy_rslt_t cyhal_adc_channel_configure | ( | cyhal_adc_channel_t * | obj, |
const cyhal_adc_channel_config_t * | config | ||
) |
Update the ADC channel configuration.
[in] | obj | The ADC channel object |
[in] | config | The configuration to apply |
void cyhal_adc_channel_free | ( | cyhal_adc_channel_t * | obj | ) |
Uninitialize the ADC channel and cyhal_adc_channel_t object.
[in,out] | obj | The ADC channel object |
uint16_t cyhal_adc_read_u16 | ( | const cyhal_adc_channel_t * | obj | ) |
Read the value from the ADC pin, represented as an unsigned 16bit value where 0x0000 represents the minimum value in the ADC's range, and 0xFFFF represents the maximum value in the ADC's range.
If continous scanning is disabled, this will block while a conversion is performed on the selected channel, then return the result. Depending on the ADC speed this function may block for some time. If continuous scanning is enabled, this will return the value from the most recent conversion of the specified channel (if called shortly after enabling continuous scanning it may block until at least one conversion has been performed on this channel).
[in] | obj | The ADC object |
int32_t cyhal_adc_read | ( | const cyhal_adc_channel_t * | obj | ) |
Read the value from ADC pin, represented as a 32-bit signed, right-aligned value.
This is a 'resolution'-bit value, sign-extended to 32 bits. If the vplus signal is below the vminus signal, the result will be negative. If the vplus signal is above the vminus signal, the result will be positive. If continous scanning is disabled, this will block while a conversion is performed on the selected channel, then return the result. Depending on the ADC speed this function may block for some time. If continuous scanning is enabled, this will return the value from the most recent conversion of the specified channel (if called shortly after enabling continuous scanning it may block until at least one conversion has been performed on this channel).
[in] | obj | The ADC object |
int32_t cyhal_adc_read_uv | ( | const cyhal_adc_channel_t * | obj | ) |
Read the value from ADC pin, in microvolts.
If continous scanning is disabled, this will block while a conversion is performed on the selected channel, then return the result. Depending on the ADC speed this function may block for some time. If continuous scanning is enabled, this will return the value from the most recent conversion of the specified channel (if called shortly after enabling continuous scanning it may block until at least one conversion has been performed on this channel).
[in] | obj | The ADC object |
cy_rslt_t cyhal_adc_read_async | ( | cyhal_adc_t * | obj, |
size_t | num_scan, | ||
int32_t * | result_list | ||
) |
Scan the specified ADC channels in the background and copy the results into the array pointed to by result_list
.
Results are represented as 32-bit signed, right-aligned values. That is, they are 'resolution'-bit values, sign-extended to 32 bits. If the vplus signal is below the vminus signal, the result will be negative. If the vplus signal is above the vminus signal, the result will be positive.
If continuous scanning is disabled, this will trigger num_scan new scans and copy the results into result_list
once the scan is completed.
If continuous scanning is enabled, this will copy the results of num_scan scans into the result_list as they complete, beginning with the most recently completed scan (if one exists).
Scan results are placed sequentially into result_list. That is, result_list will contain all of the results from the first scan, followed by all of the results from the second scan, etc. If channels exist that are initialized but not enabled, they will consume locations in result_list, but these values are undefined.
When the requested number of scans have been completed, the CYHAL_ADC_ASYNC_READ_COMPLETE event will be raised.
cyhal_adc_set_async_mode can be used to control whether this uses DMA or a SW (CPU-driven) transfer.
[in] | obj | ADC to read from |
[in] | num_scan | The number of scans of each channel that should be read |
[in] | result_list | The array where results should be. This must be of length num_scan * initialized_channels, where initialized_channels is the number of channels that have been initialized for this ADC (and not later freed) via cyhal_adc_channel_init_diff |
cy_rslt_t cyhal_adc_read_async_uv | ( | cyhal_adc_t * | obj, |
size_t | num_scan, | ||
int32_t * | result_list | ||
) |
Scan the specified ADC channels in the background and copy the conversion results in microvolts into the array pointed to by result_list
.
If continuous scanning is disabled, this will trigger num_scan new scans and copy the results into result_list
once the scan is completed.
If continuous scanning is enabled, this will copy the results of num_scan scans into the result_list as they complete, beginning with the most recently completed scan (if one exists).
Scan results are placed sequentially into result_list. That is, result_list will contain all of the results from the first scan, followed by all of the results from the second scan, etc. If channels exist that are initialized but not enabled, they will consume locations in result_list, but these values are undefined.
When the requested number of scans have been completed, the CYHAL_ADC_ASYNC_READ_COMPLETE event will be raised.
cyhal_adc_set_async_mode can be used to control whether this uses DMA or a SW (CPU-driven) transfer.
[in] | obj | ADC to read from |
[in] | num_scan | The number of scans of each channel that should be read |
[in] | result_list | The array where results should be. This must be of length num_scan * initialized_channels, where initialized_channels is the number of channels that have been initialized for this ADC (and not later freed) via cyhal_adc_channel_init_diff |
cy_rslt_t cyhal_adc_set_async_mode | ( | cyhal_adc_t * | obj, |
cyhal_async_mode_t | mode, | ||
uint8_t | dma_priority | ||
) |
Set the mechanism that is used to perform ADC asynchronous transfers.
The default is SW.
[in] | obj | The ADC object |
[in] | mode | The transfer mode |
[in] | dma_priority | The priority, if DMA is used. Valid values are the same as for cyhal_dma_init. If DMA is not selected, the only valid value is CYHAL_DMA_PRIORITY_DEFAULT, and no guarantees are made about prioritization. |
void cyhal_adc_register_callback | ( | cyhal_adc_t * | obj, |
cyhal_adc_event_callback_t | callback, | ||
void * | callback_arg | ||
) |
Register an ADC callback handler.
This function will be called when one of the events enabled by cyhal_adc_enable_event occurs.
[in] | obj | The ADC object |
[in] | callback | The callback handler which will be invoked when the interrupt fires |
[in] | callback_arg | Generic argument that will be provided to the callback when called |
void cyhal_adc_enable_event | ( | cyhal_adc_t * | obj, |
cyhal_adc_event_t | event, | ||
uint8_t | intr_priority, | ||
bool | enable | ||
) |
Configure ADC events.
When an enabled event occurs, the function specified by cyhal_adc_register_callback will be called.
[in] | obj | The ADC object |
[in] | event | The ADC event type |
[in] | intr_priority | The priority for NVIC interrupt events |
[in] | enable | True to turn on specified events, False to turn off |