1.34.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