Jump to main content

##

# 3.13.1 Analog-to-Digital Converter (ADC)

- Up to 12-bit resolution of the numerical output, signed or unsigned

- Signed outputs left- or right-adjusted

- Up to 5.14 Msps conversion rate per channel

- Up to 4 Shared Analog ADC SAR cores (bound by limited CSR and pin-out resources) for an aggregate conversion rate of 20.5 Msps per entire ADC module by performing up to 4 conversions simultaneously

- Up to 64 analog inputs (maximum of 16 channels per core).

- Single-ended and/or differential inputs on a per channel basis for all channels.

- Up to 16 trigger sources, off-chip hardware or on-chip hardware or software generated

- Edge or level active triggering modes, to generate single conversions or bursts of conversions

- A scan trigger per each shared Analog ADC SAR Core to start a scan cycle which can individually include or not any of the analog inputs assigned to that Analog ADC SAR Core

- Up to 4 scan cycles running simultaneously

- Any channel can select any of the 16 trigger sources or the scan trigger as its own trigger

- The scan trigger itself can select any of the 16 trigger sources as its own source Programmable sampling time, individual for each shared Analog ADC SAR Core

- Each analog input / channel output register can be read from an general dedicated APB output register (user writes the CORDYID and CHRDYID then reads the CHRDYDATA register).

## Using The Library

Interrupt mode:

    #include <stddef.h>                     // Defines NULL
    #include <stdbool.h>                    // Defines true
    #include <stdlib.h>                     // Defines EXIT_FAILURE
    #include "definitions.h"                // SYS function prototypes

    #define ADC_VREF                             (3.3f)

    volatile uint32_t adc_data[3];
    volatile bool adc_sequence_done = false;
    volatile bool adc_ch2_done = false;
    float adc_inp_vol;
    // *****************************************************************************
    // *****************************************************************************
    // Section: Main Entry Point
    // *****************************************************************************
    // *****************************************************************************
    void ADC_EventHandler(ADC_CORE_INT status, uintptr_t context)
    {
        /* ADC1_CH0 and ADC1_CH1 are configured for scan trigger */
        if (status & ADC_CORE_INT_EOSRDY)
        {
            adc_data[0] = ADC_ResultGet(ADC_CORE_NUM1, ADC_CH0);

            adc_data[1] = ADC_ResultGet(ADC_CORE_NUM1, ADC_CH1);

            adc_sequence_done = true;
        }
        /* ADC1_CH2 is configured for Global (Edge) Software trigger */
        if (status & ADC_CORE_INT_CHRDY_2)
        {
            adc_data[2] = ADC_ResultGet(ADC_CORE_NUM1, ADC_CH2);

            adc_ch2_done = true;
        }
    }

    int main ( void )
    {
        /* Initialize all modules */
        SYS_Initialize ( NULL );

        printf("\r\n *********************************************** \r\n");
        printf("\r\n           ADC INTERRUPT DEMO \r\n");
        printf("\r\n *********************************************** \r\n");

        ADC_CORE1CallbackRegister(ADC_EventHandler, 0);
        RTC_Timer32Start();

        while ( true )
        {
            if (SWITCH_Get() == 0)
            {
                // Wait for switch release
                while (SWITCH_Get() == 0);

                ADC_GlobalEdgeConversionStart();
            }

            if (adc_sequence_done == true)
            {
    			adc_sequence_done = false;

                adc_inp_vol = (uint16_t)adc_data[0] * ADC_VREF / 4095U;

                printf("\r\n ADC1_AIN0: ADC Count: 0x%03x, ADC Input Voltage = %d.%02d V \r\n",
                        (uint16_t)adc_data[0], (int)adc_inp_vol, (int)((adc_inp_vol - (int)adc_inp_vol)*100.0));

                adc_inp_vol = (uint16_t)adc_data[1] * ADC_VREF / 4095U;

                printf("\r\n ADC1_AIN1: ADC Count: 0x%03x, ADC Input Voltage = %d.%02d V \r\n",
                        (uint16_t)adc_data[1], (int)adc_inp_vol, (int)((adc_inp_vol - (int)adc_inp_vol)*100.0));
    		}
            if (adc_ch2_done == true)
            {
                adc_ch2_done = false;

                adc_inp_vol = (uint16_t)adc_data[2] * ADC_VREF / 4095U;

                printf("\r\n ADC1_AIN2: ADC Count: 0x%03x, ADC Input Voltage = %d.%02d V \r\n",
                        (uint16_t)adc_data[2], (int)adc_inp_vol, (int)((adc_inp_vol - (int)adc_inp_vol)*100.0));
            }
        }

        /* Execution should not come here during normal operation */

        return ( EXIT_FAILURE );
    }

Polling mode:

    #include <stddef.h>                     // Defines NULL
    #include <stdbool.h>                    // Defines true
    #include <stdlib.h>                     // Defines EXIT_FAILURE
    #include "definitions.h"                // SYS function prototypes

    #define ADC_VREF                             (3.3f)

    // *****************************************************************************
    // *****************************************************************************
    // Section: Main Entry Point
    // *****************************************************************************
    // *****************************************************************************
    uint32_t adc_data;
    float adc_inp_vol;

    int main ( void )
    {
        /* Initialize all modules */
        SYS_Initialize ( NULL );

        while ( true )
        {
            ADC_GlobalEdgeConversionStart();

            while (ADC_ChannelResultIsReady(ADC_CORE_NUM1, ADC_CH0) == false);

            adc_data = ADC_ResultGet(ADC_CORE_NUM1, ADC_CH0);

            adc_inp_vol = (uint16_t)adc_data * ADC_VREF / 4095U;

            printf("ADC1_AIN0: ADC Count: 0x%03x, ADC Input Voltage = %d.%02d V\r",
                (uint16_t)adc_data, (int)adc_inp_vol, (int)((adc_inp_vol - (int)adc_inp_vol)*100.0));
        }

        /* Execution should not come here during normal operation */

        return ( EXIT_FAILURE );
    }

## Library Interface

ADC Controller peripheral library provides the following interfaces:

Functions

Name | Description
--- | ---
ADCx_Initialize | Initializes given instance of ADC peripheral
ADCx_Enable | Enables the ADC module
ADCx_Disable | Disables the ADC module
ADC_CompareEnable | Enables digital comparisons for the given channel on the specified ADC core
ADC_CompareDisable | Disables digital comparisons for the given channel on the specified ADC core
ADC_CompareWinThresholdSet | Configures the low and high threshold values for the comparator on the specified ADC core
ADC_CompareWinModeSet | Configures the low and high threshold values for the comparator on the specified ADC core
ADC_GlobalInterruptsStatusGet | Returns the global interrupt status
ADC_CoreInterruptsEnable | Enables the specified ADC core's interrupt
ADC_CoreInterruptsDisable | Disable the specified ADC core's interrupts
ADC_CoreInterruptsStatusGet | Returns the specified ADC core's interrupt status
ADC_CoreInterruptsStatusClear | Clears the specified ADC core's interrupt status
ADC_GlobalEdgeConversionStart | Generates global edge trigger and starts conversion on channels configured with Global edge as the trigger source
ADC_GlobalLevelConversionStart | Starts global level trigger and starts conversion on channels configured with Global level as the trigger source
ADC_GlobalLevelConversionStop | Stops global level trigger and stops conversion on channels configured with Global level as the trigger source
ADC_SyncTriggerEnable | Enables sync trigger defined by CTRLC.CNT value
ADC_SyncTriggerDisable | Disables sync trigger
ADC_SyncTriggerCounterSet | Configures the value of CTRLC.CNT register
ADC_SoftwareControlledConversionEnable | Enables software controlled conversion on the specified ADC core's channel
ADC_ChannelSamplingStart | Enables the Analog Mux Input and starts sampling on the ADC core and channel that was specified using the ADC_SoftwareControlledConversionEnable() API
ADC_ChannelSamplingStop | Stops sampling on the ADC core and channel that was specified using the ADC_SoftwareControlledConversionEnable() API
ADC_ChannelConversionStart | Starts conversion on the ADC core and channel that was specified using the ADC_SoftwareControlledConversionEnable() API
ADC_ChannelResultIsReady | Indicates whether ADC conversion is complete on the specified ADC core's channel
ADC_EOSStatusGet | Indicates whether End of scan interrupt flag is set on the specified ADC core
ADC_ResultGet | Returns the ADC conversion value for the specified ADC core channel
ADC_FIFORead | Returns a single ADC conversion value from the ADC FIFO
ADC_FIFOBufferRead | Returns multiple ADC conversion values from the ADC FIFO
ADC_GlobalCallbackRegister | Registers the global callback function
ADC_COREnCallbackRegister | Registers the ADC core specific callback function

Data types and constants

Name | Type | Description
--- | --- | ---
ADC_CORE_INT_CMPHIT | Macro | Identifies ADC core interrupt status
ADC_FIFO_CORID_GET | Macro | Returns the ADC core id in the ADC FIFO data
ADC_FIFO_DATA_GET | Macro | Returns the ADC conversion resunt from the ADC FIFO data
ADC_FIFO_CHNID_GET | Macro | Returns the ADC channel id in the ADC FIFO data
ADC_FIFO_CNT_GET | Macro | Returns the current number of entries present in the ADC FIFO
ADC_GLOBAL_INT_CRRDY1 | Macro | Identifies ADC global interrupt status
ADC_CHANNEL_NUM | Enum | Identifies ADC channel number
ADC_CORE_NUM | Enum | Identifies ADC core
ADC_CORE_CALLBACK | Typedef | Defines the function pointer data type and function signature for the adc peripheral core callback function
ADC_GLOBAL_CALLBACK | Typedef | Defines the function pointer data type and function signature for the adc peripheral global callback function
ADC_CORE_CALLBACK_OBJECT | Struct | ADC Core events Callback structure
ADC_GLOBAL_CALLBACK_OBJECT | Struct | ADC Global Callback structure