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 |