Jump to main content

##

# 3.38.1 Analog Front-End Controller (AFEC)

- 12-bit Resolution up to 16-bit Resolution by Digital Averaging

- Wide Range of Power Supply Operation

- Selectable Single-ended or Differential Input Voltage

- Selectable Single or Dual Sample-and-Hold Mode

- Programmable Gain for Maximum Full-Scale Input Range 0–VDD

- Programmable Offset Per Channel

- Automatic Correction of Offset and Gain Errors

- Integrated Multiplexers Offering Up to 12 Independent Analog Inputs

- Individual Enable and Disable of Each Channel

- Hardware or Software Trigger (External trigger pin, Timer counter outputs (corresponding TIOA trigger), PWM event line)

- Drive of PWM Fault Input

- DMA Support

- Possibility of AFE Timings Configuration

- Two Sleep Modes and Conversion Sequencer (Automatic wakeup on trigger and back to sleep mode after conversions of all enabled channels, Possibility of customized channel sequence)

## 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

    /*****************************************************
     AFEC CH0 - PB01 - Connect to DACC output PB13
     AFEC CH5 - PC30 - connect to Vcc
     AFEC_CH6 - PC31 - Connect to GND
     *****************************************************/

    #define AFEC_VREF               (3.3f)
    #define DAC_COUNT_INCREMENT     (124U)  // Equivalent to 0.1V
    #define DAC_COUNT_MAX           (4095U)

    volatile uint16_t adc_ch0_count, adc_ch5_count, adc_ch6_count;

    float adc_ch0_voltage, adc_ch5_voltage, adc_ch6_voltage;

    volatile bool result_ready;
    /* Initial DAC count which is midpoint = 1.65V*/
    uint16_t dac_count=0x800;

    void switch_handler( PIO_PIN pin, uintptr_t context )
    {
        /* Write next data sample */
        dac_count = dac_count + DAC_COUNT_INCREMENT;

        if (dac_count > DAC_COUNT_MAX)
                dac_count=0;

        DACC_DataWrite(DACC_CHANNEL_0, dac_count);
    }

    /* This function is called after conversion of last channel in the user sequence */
    void AFEC_EventHandler(uint32_t status, uintptr_t context)
    {
        /* Read the result of 3 channels*/
        adc_ch5_count = AFEC1_ChannelResultGet(CH5_VDD);
        adc_ch6_count = AFEC1_ChannelResultGet(CH6_GND);
        adc_ch0_count = AFEC1_ChannelResultGet(CH0_SINE_WAVE);

        result_ready = true;

    }

    // *****************************************************************************
    // *****************************************************************************
    // Section: Main Entry Point
    // *****************************************************************************
    // *****************************************************************************

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

        PIO_PinInterruptCallbackRegister(SWITCH_PIN, &switch_handler, (uintptr_t) NULL );
        PIO_PinInterruptEnable(SWITCH_PIN);

        /* Register callback function for AFEC end of conversion interrupt*/
        AFEC1_CallbackRegister(AFEC_EventHandler, (uintptr_t)NULL);

        /* Write first data sample in DAC channel 0 and channel 1*/
        DACC_DataWrite(DACC_CHANNEL_0, dac_count);

        /* Start the timer to trigger ADC conversion every 50 ms*/
        TC1_CH0_CompareStart();

        printf("\n\r---------------------------------------------------------");
        printf("\n\r                    AFEC User Sequence Demo                 ");
        printf("\n\r---------------------------------------------------------\n\r");
        printf("CH0 Count  CH0 Voltage  CH5 Count  CH5 Voltage  CH6 Count  CH6 Voltage \n\r");

        while ( true )
        {
            /* Check if result is ready to be transmitted to console */
            if (result_ready == true)
            {
                adc_ch5_voltage = (float)adc_ch5_count * AFEC_VREF/4095U;
                adc_ch6_voltage = (float)adc_ch6_count * AFEC_VREF/4095U;
                adc_ch0_voltage = (float)adc_ch0_count * AFEC_VREF/4095U;
                printf("0x%03x      %0.2f V       0x%03x      %0.2f V       0x%03x      %0.2f V \t\r", \
                        adc_ch0_count, adc_ch0_voltage, adc_ch5_count, adc_ch5_voltage, adc_ch6_count, adc_ch6_voltage);

                result_ready = false;
            }
        }

        /* 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 <stdio.h>
    #include "definitions.h"                // SYS function prototypes

    #define AFEC_VREF               (3.3f)
    #define DAC_COUNT_INCREMENT     (124U)  // equivalent to 0.1V
    #define DAC_COUNT_MAX           (4095U)

    uint16_t adc_count;
    float input_voltage;
    /* Initial value of dac count which is midpoint = 1.65 V*/
    uint16_t dac_count = 0x800;

    void switch_handler( PIO_PIN pin, uintptr_t context )
    {
        /* Write next data sample */
        dac_count = dac_count + DAC_COUNT_INCREMENT;

        if (dac_count > DAC_COUNT_MAX)
                dac_count=0;

        DACC_DataWrite(DACC_CHANNEL_0, dac_count);
    }

    // *****************************************************************************
    // *****************************************************************************
    // Section: Main Entry Point
    // *****************************************************************************
    // *****************************************************************************

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

        PIO_PinInterruptCallbackRegister(SWITCH_PIN, &switch_handler, (uintptr_t) NULL );
        PIO_PinInterruptEnable(SWITCH_PIN);

        printf("\n\r---------------------------------------------------------");
        printf("\n\r                    AFEC Demo                 ");
        printf("\n\r---------------------------------------------------------\n\r");
        printf("Press switch to change the DAC output. \r\n");

        SYSTICK_TimerStart();

        DACC_DataWrite(DACC_CHANNEL_0, dac_count);

        while (1)
        {
            /* Start ADC conversion */
            AFEC1_ConversionStart();

            /* Wait till ADC conversion result is available */
            while(!AFEC1_ChannelResultIsReady(AFEC_CH0))
            {

            };

            /* Read the ADC result */
            adc_count = AFEC1_ChannelResultGet(AFEC_CH0);
            input_voltage = (float)adc_count * AFEC_VREF / 4095U;

            printf("ADC Count = 0x%03x, ADC Input Voltage = %0.2f V \r",adc_count, input_voltage);

            SYSTICK_DelayMs(500);
        }

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

        return ( EXIT_FAILURE );
    }

## Library Interface

Analog Front-End Controller peripheral library provides the following interfaces:

Functions

Name | Description
--- | ---
AFECx_Initialize | Initializes given instance of AFEC peripheral
AFECx_ChannelsEnable | Enables the ADC channels
AFECx_ChannelsDisable | Disables the ADC channels
AFECx_ChannelsInterruptEnable | Enables the ADC interrupt sources
AFECx_ChannelsInterruptDisable | Disables the ADC interrupt sources
AFECx_ConversionStart | Starts the ADC conversion of all the enabled channels with the software trigger
AFECx_ChannelResultIsReady | Returns the status of the channel conversion
AFECx_ChannelResultGet | Reads the conversion result of the channel
AFECx_ConversionSequenceSet | Sets the user sequence of the channel conversion
AFECx_ChannelGainSet | Writes the gain of the channel
AFECx_ChannelOffsetSet | Writes the channel offset
AFECx_CallbackRegister | Registers the function to be called from interrupt

Data types and constants

Name | Type | Description
--- | --- | ---
AFEC_CHANNEL_NUM | Enum | Identifies AFEC channel number
AFEC_INTERRUPT_MASK | Enum | Identifies channel interrupt sources mask
AFEC_CHANNEL_MASK | Enum | Identifies AFEC channel mask
AFEC_CHANNEL_GAIN | Enum | Identifies programmable gain setting
AFEC_CALLBACK | Typedef | Defines the function pointer data type and function signature for the afec peripheral callback function
AFEC_CALLBACK_OBJECT | Struct | AFEC Callback structure