Appendix: Example Application Source Code

/* ----------------------------------------------------------------------------
 *         SAM Software Package License
 * ----------------------------------------------------------------------------
 * Copyright (c) 2011, Atmel Corporation
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the disclaimer below.
 *
 * Atmel's name may not be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ----------------------------------------------------------------------------
 */


/** \file
 *
 *  This file contains all the specific code for the AFEC Application Note example.
 *
 */

/*----------------------------------------------------------------------------
 *        Headers
 *----------------------------------------------------------------------------*/

#include "board.h"
#include <stdbool.h>
#include <stdio.h>
#include <string.h>


/*----------------------------------------------------------------------------
 *        Local definitions
 *----------------------------------------------------------------------------*/

/** First AFE Channel used*/
#define TEST_CHANNEL_SINGLE_ENDED			5	//AFE0_AD5->PB2
#define TEST_CHANNEL_SINGLE_ENDED_DUALSH	2		//AFE0_AD2->PB3 & AFE0_AD8->PA19 (Channel 2 in Dual Sample & hold Single Ended mode)


/** AFE Channel DAC Offset */
#define CHANNEL_OFFSET	0x200

/* AFE Clock Value */
#define AFE_CLK         10000000

/*----------------------------------------------------------------------------
 *        Local functions
 *----------------------------------------------------------------------------*/



/**
 *  \brief Initialize AFE in Single-Ended.
 *
 */
static void _afe_initialization_SingleEnded(void) {
	
	/* Step 1: Configure the pins for AFEC. (If not already done by default) */
	/* Step 2: AFEC init */
	AFEC_Initialize( AFEC0, ID_AFEC0 );
	
	/*Step 3: AFEC Mode Register Configuration */
	AFEC_SetModeReg(AFEC0,AFEC_MR_FREERUN_OFF|AFEC_MR_TRANSFER(1)|AFEC_MR_TRACKTIM(2)| AFEC_MR_ONE| AFEC_MR_STARTUP_SUT512);
	
	/* Step 4	Set AFEC clock AFEC_SetClock() */
	AFEC_SetClock( AFEC0, AFE_CLK, BOARD_MCK ) ;
	
	/* Step 5	Select the active channel using the Macro definition AFEC_EnableChannel(). */
	AFEC_EnableChannel(AFEC0, TEST_CHANNEL_SINGLE_ENDED);
	
	/* Step 6	Adjust the channel level offset */
	AFEC_SetAnalogOffset(AFEC0, TEST_CHANNEL_SINGLE_ENDED, CHANNEL_OFFSET);
/* Step 7 Enable the PGA 0 and 1 of the AFEC0 and adjust the performances by tuning the AFE Bias Current Control */
	AFEC_SetAnalogControl(AFEC0, AFEC_ACR_IBCTL(1) | AFEC_ACR_PGA0_ON |	AFEC_ACR_PGA1_ON );
	
	/* Step 8 Configure the Extended Mode Register by disabling the Averaging, enabling the channel tag and using the Single Trigger Mode */
	AFEC_SetExtModeReg(AFEC0,0|AFEC_EMR_RES_NO_AVERAGE|AFEC_EMR_SIGNMODE_SE_UNSG_DF_SIGN| AFEC_EMR_TAG | AFEC_EMR_STM ); 
}

/**
 *  \brief Initialize AFE in Single-Ended with digital averaging OSR 256.
 *
 */
static void _afe_initialization_SingleEnded_OSR256(void) {
	
	/* Step 1: Configure the pins for AFEC. (If not already done by default) */
	/* Step 2: AFEC init */
	AFEC_Initialize( AFEC0, ID_AFEC0 );
	
	/*Step 3: AFEC Mode Register Configuration */
	AFEC_SetModeReg(AFEC0,AFEC_MR_FREERUN_OFF|AFEC_MR_TRANSFER(1)|AFEC_MR_TRACKTIM(2)| AFEC_MR_ONE| AFEC_MR_STARTUP_SUT512);
	
	/* Step 4	Set AFEC clock AFEC_SetClock() */
	AFEC_SetClock( AFEC0, AFE_CLK, BOARD_MCK ) ;
	
	/* Step 5	Select the active channel using the Macro definition AFEC_EnableChannel(). */
	AFEC_EnableChannel(AFEC0, TEST_CHANNEL_SINGLE_ENDED);
	
	/* Step 6	Adjust the channel level offset */
	AFEC_SetAnalogOffset(AFEC0, TEST_CHANNEL_SINGLE_ENDED, CHANNEL_OFFSET);
	
	/* Step 7 Enable the PGA 0 and 1 of the AFEC0 and adjust the performances by tuning the AFE Bias Current Control */
	AFEC_SetAnalogControl(AFEC0, AFEC_ACR_IBCTL(1) | AFEC_ACR_PGA0_ON |	AFEC_ACR_PGA1_ON );
	
	/* Step 8 Configure the Extended Mode Register by enabling the Averaging, enabling the channel tag and using the Single Trigger Mode */
	AFEC_SetExtModeReg(AFEC0,0|AFEC_EMR_RES_OSR256|AFEC_EMR_SIGNMODE_SE_UNSG_DF_SIGN| AFEC_EMR_TAG | AFEC_EMR_STM ); 
}


static void _afe_initialization_SingleEnded_DualSH(void) {
	
	/* Step 1: Configure the pins for AFEC. (If not already done by default) */
	/* Step 2: AFEC init */
	AFEC_Initialize( AFEC0, ID_AFEC0 );
	
	/* Step 3: AFEC Mode Register Configuration */
	AFEC_SetModeReg(AFEC0,AFEC_MR_FREERUN_OFF|AFEC_MR_TRANSFER(1)|AFEC_MR_TRACKTIM(2)| AFEC_MR_ONE| AFEC_MR_STARTUP_SUT512);
	
	/* Step 4: Enable the FAEC Dual Sample And Hold feature for the channel 2 */
	AFEC0->AFEC_SHMR |= AFEC_SHMR_DUAL2;
	
	/* Step 5	Set AFEC clock AFEC_SetClock() */
	AFEC_SetClock( AFEC0, AFE_CLK, BOARD_MCK ) ;
	
	/* Step 6	Select the active channel using the Macro definition AFEC_EnableChannel(). */
	AFEC_EnableChannel(AFEC0, TEST_CHANNEL_SINGLE_ENDED_DUALSH);	// the channel is different than in previous example.
	
	/* Step 7	Adjust the offset level of each channels */
	AFEC_SetAnalogOffset(AFEC0, TEST_CHANNEL_SINGLE_ENDED_DUALSH, CHANNEL_OFFSET);
	AFEC_SetAnalogOffset(AFEC0, 8, CHANNEL_OFFSET);
	
	/* Step 8 Enable the PGA 0 and 1 of the AFEC0 and adjust the performances by tuning the AFE Bias Current Control */
	AFEC_SetAnalogControl(AFEC0, AFEC_ACR_IBCTL(1) | AFEC_ACR_PGA0_ON |	AFEC_ACR_PGA1_ON );
	
	/* Step 9 Configure the Extended Mode Register by enabling the Averaging, enabling the channel tag and using the Single Trigger Mode */
	AFEC_SetExtModeReg(AFEC0,0|AFEC_EMR_RES_NO_AVERAGE|AFEC_EMR_SIGNMODE_SE_UNSG_DF_SIGN| AFEC_EMR_TAG | AFEC_EMR_STM );
}


static void _afe_initialization_SingleEnded_DualSH_OSR256(void) {
	
	/* Step 1: Configure the pins for AFEC. (If not already done by default) */
	/* Step 2: AFEC init */
	AFEC_Initialize( AFEC0, ID_AFEC0 );
	
	/* Step 3: AFEC Mode Register Configuration */
	AFEC_SetModeReg(AFEC0,AFEC_MR_FREERUN_OFF|AFEC_MR_TRANSFER(1)|AFEC_MR_TRACKTIM(2)| AFEC_MR_ONE| AFEC_MR_STARTUP_SUT512);
	
	/* Step 4: Enable the FAEC Dual Sample And Hold feature for the channel 2 */
	AFEC0->AFEC_SHMR |= AFEC_SHMR_DUAL2;
	
	/* Step 5	Set AFEC clock AFEC_SetClock() */
	AFEC_SetClock( AFEC0, AFE_CLK, BOARD_MCK ) ;
	
	/* Step 6	Select the active channel using the Macro definition AFEC_EnableChannel(). */
	AFEC_EnableChannel(AFEC0, TEST_CHANNEL_SINGLE_ENDED_DUALSH);	// the channel is different than in previous example.
	
	/* Step 7	Adjust the offset level of each channels */
	AFEC_SetAnalogOffset(AFEC0, TEST_CHANNEL_SINGLE_ENDED_DUALSH, CHANNEL_OFFSET);
	AFEC_SetAnalogOffset(AFEC0, 8, CHANNEL_OFFSET);
	
	/* Step 8 Enable the PGA 0 and 1 of the AFEC0 and adjust the performances by tuning the AFE Bias Current Control */
	AFEC_SetAnalogControl(AFEC0, AFEC_ACR_IBCTL(1) | AFEC_ACR_PGA0_ON |	AFEC_ACR_PGA1_ON );
	
	/* Step 9 Configure the Extended Mode Register by enabling the Averaging, enabling the channel tag and using the Single Trigger Mode */
	AFEC_SetExtModeReg(AFEC0,0|AFEC_EMR_RES_OSR256|AFEC_EMR_SIGNMODE_SE_UNSG_DF_SIGN| AFEC_EMR_TAG | AFEC_EMR_STM );
}


/*----------------------------------------------------------------------------
 *        Exported functions
 *----------------------------------------------------------------------------*/
/**
 *  \brief getting-started Application entry point.
 *
 *  \return Unused (ANSI-C compatibility).
 */
extern int main( void )
{
	/* Local variable */
	uint32_t ch;
	uint32_t voltage;
	uint8_t key = 0;
	uint32_t i=0;
	
	/*** SYSTEM INIT ***/	
	/* Disable watchdog */
	WDT_Disable( WDT ) ;
	/* Enable I and D cache */
	SCB_EnableICache();
	SCB_EnableDCache();

	/* Output example information */
	printf( "\n\r-- AFE Application Note Example %s --\n\r", SOFTPACK_VERSION ) ;
	printf( "-- %s\n\r", BOARD_NAME ) ;
	printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME);
	
	/*** LED CONFIGURATION ***/
	/* Conifgure led */
	LED_Configure( 1 ) ;
	/* The led is lit ON */
	LED_Set( 1 );
	
	
	while ( 1 ) 
	{
		
		/* Display menu lines */
		printf( "\n\r Choose your AFEC Configuration:") ;
		printf( "\n\r\t -1-: Single Ended with Software Trigger") ;
		printf( "\n\r\t -2-: Single Ended with Software Trigger with averaging ON") ;
		printf( "\n\r\t -3-: Single Ended, Dual Sample and Hold with Software Trigger") ;
		printf( "\n\r\t -4-: Single Ended, Dual Sample and Hold with Software Trigger with averaging ON") ;
		
		/*waiting for a typed value*/                                                          
		key = DBG_GetChar();
		
		/* State machine depending on the wanted AFEC configuration */
		switch (key){
				
				/* -1-: Single Ended with Software Trigger */
				case '1':
					printf( "\n\n\n\r 1: You chose : Single Ended with Software Trigger") ;
				
					/* Step 1 to step 8: Initialize the AFE */
					_afe_initialization_SingleEnded();
				
					/* Step 9: Start Conversion by software trigger */
					AFEC_StartConversion(AFEC0);
				
					/* Step 10: Wait for the end of the conversion by polling status with AFEC_GetStatus() */
					while (!(AFEC_GetStatus(AFEC0) & AFEC_ISR_EOC5));
				
					LED_Toggle( 1 );
				
					/* Step 11: Finally, get the converted data and the channel used using AFEC_GetConvertedData() or AFEC_GetLastConvertedData() */;
					printf("\n\rCH Voltage(mV) \n\r");
					ch =  (AFEC_GetLastConvertedData(AFEC0) & AFEC_LCDR_CHNB_Msk ) >> AFEC_LCDR_CHNB_Pos;
				
					/* Rescaling and displaying of the result */
					voltage = ((AFEC0->AFEC_CDR & AFEC_CDR_DATA_Msk)) * 3253/4096;	//3253 is the Vref volatge in mV
					printf("%02u %04u (%04u is the code value)\n\r" ,(unsigned int)ch,(unsigned int)voltage,(AFEC_GetLastConvertedData(AFEC0) & AFEC_LCDR_LDATA_Msk));
	
				break;
				
				/* -2-: Single Ended with Software Trigger with averaging ON */
				case '2': 
					printf( "\n\n\n\r 2: You chose : Single Ended with Software Trigger and Digital averaging") ;
				
					/* Step 1 to step 8: Initialize the AFE */
					_afe_initialization_SingleEnded_OSR256();
				
					/* Step 9: Start Conversion by software trigger */
					AFEC_StartConversion(AFEC0);
				
					/* Step 10: Wait for the end of the conversion by polling status with AFEC_GetStatus() */
					while (!(AFEC_GetStatus(AFEC0) & AFEC_ISR_EOC5));
LED_Toggle( 1 );
				
					/* Step 11: Finally, get the converted data and the channel used using AFEC_GetConvertedData() or AFEC_GetLastConvertedData() */
					printf("\n\rCH Voltage(mV) \n\r");
				
					/* Rescaling and displaying of the result */
					ch =  (AFEC_GetLastConvertedData(AFEC0) & AFEC_LCDR_CHNB_Msk ) >> AFEC_LCDR_CHNB_Pos;
					voltage = ((AFEC_GetLastConvertedData(AFEC0) & AFEC_LCDR_LDATA_Msk)) * 3253/65536;	//3253 is the Vref voltage in mV this time the scale factor is 65536 (16-bit resolution)
					printf("%02u %04u (%04u is the code value)\n\r" ,(unsigned int)ch,(unsigned int)voltage,(AFEC_GetLastConvertedData(AFEC0) & AFEC_LCDR_LDATA_Msk));
				
				break;
					
				/* -3-: Single Ended, Dual Sample and Hold with Software Trigger */
				case '3':
					printf( "\n\n\n\r 3: You chose : Single Ended, Dual Sample and Hold with Software Trigger") ;
					
					/* Step 1 to step 9: Initialize the AFE */
					_afe_initialization_SingleEnded_DualSH();
					
					/* Step 10: Start Conversion by software trigger */
					AFEC_StartConversion(AFEC0);
					
					/* Step 11: Wait for the end of the conversion by polling status with AFEC_GetStatus() */
					while (!(AFEC_GetStatus(AFEC0) & AFEC_ISR_EOC2)); //this time the channel is replaced by channel 2: First Channel
					
					LED_Toggle( 1 );
					
					/* Step 12: Finally, get the converted data and the channel used using AFEC_GetConvertedData() or AFEC_GetLastConvertedData() */
					printf("\n\rCH Voltage(mV) \n\r");
					
					/* Rescaling and displaying of the result of value 1 */
					ch =  2;
					voltage = (AFEC_GetConvertedData(AFEC0, AFEC_CSELR_CSEL(2))) * 3253/4096; //3253 is the Vref voltage in mV
					printf("%02u %04u (%04u is the code value)\n\r" ,(unsigned int)ch,(unsigned int)voltage,AFEC_GetConvertedData(AFEC0, AFEC_CSELR_CSEL(2)));
					
					
					/* Step 13: Reproducing step 11 for the next channel : Wait for the end of the conversion by polling status with AFEC_GetStatus() */
					while (!(AFEC_GetStatus(AFEC0) & AFEC_ISR_EOC8)); //this time the channel is replaced by channel 8: second Channel
					
					/* Rescaling and displaying of the result of value 2*/
					ch =  (AFEC_GetLastConvertedData(AFEC0) & AFEC_LCDR_CHNB_Msk ) >> AFEC_LCDR_CHNB_Pos;
					voltage = (AFEC_GetConvertedData(AFEC0, AFEC_CSELR_CSEL(8))) * 3253/4096;	//3253 is the Vref volatge in mV
					printf("%02u %04u (%04u is the code value)\n\r" ,(unsigned int)ch,(unsigned int)voltage,AFEC_GetConvertedData(AFEC0, AFEC_CSELR_CSEL(8)));
					
				break;
					
				/* -4-: Single Ended, Dual Sample and Hold with Software Trigger with averaging ON */	
				case '4':
					printf( "\n\n\n\r 3: You chose : Single Ended, Dual Sample and Hold with Software Trigger with averaging ON") ;
					
					/* Step 1 to step 9: Initialize the AFE */
					_afe_initialization_SingleEnded_DualSH_OSR256();
					
					/* Step 10: Start Conversion by software trigger */
					AFEC_StartConversion(AFEC0);
					
					/* Step 11: Wait for the end of the conversion by polling status with AFEC_GetStatus() */
					while (!(AFEC_GetStatus(AFEC0) & AFEC_ISR_EOC2)); //this time the channel is replaced by channel 2: First Channel
					
					LED_Toggle( 1 );
					
					/* Step 12: Finally, get the converted data and the channel used using AFEC_GetConvertedData() or AFEC_GetLastConvertedData() */
					printf("\n\rCH Voltage(mV) \n\r");
					
					/* Rescaling and displaying of the result of value 1 */
					ch =  2;
					voltage = (AFEC_GetConvertedData(AFEC0, AFEC_CSELR_CSEL(2))) * 3253/65536; //3253 is the Vref voltage in mV this time the scale factor is 65536 (16-bit resolution)
					printf("%02u %04u (%04u is the code value)\n\r" ,(unsigned int)ch,(unsigned int)voltage,AFEC_GetConvertedData(AFEC0, AFEC_CSELR_CSEL(2)));
					
					
					/* Step 13: Reproducing step 11 for the next channel : Wait for the end of the conversion by polling status with AFEC_GetStatus() */
					while (!(AFEC_GetStatus(AFEC0) & AFEC_ISR_EOC8)); //this time the channel is replaced by channel 8: second Channel
					
					/* Rescaling and displaying of the result of value 2*/
					ch =  (AFEC_GetLastConvertedData(AFEC0) & AFEC_LCDR_CHNB_Msk ) >> AFEC_LCDR_CHNB_Pos;
		voltage = (AFEC_GetConvertedData(AFEC0, AFEC_CSELR_CSEL(8))) * 3253/65536;	//3253 is the Vref volatge in mV this time the scale factor is 65536 (16-bit resolution)
					printf("%02u %04u (%04u is the code value)\n\r" ,(unsigned int)ch,(unsigned int)voltage,AFEC_GetConvertedData(AFEC0, AFEC_CSELR_CSEL(8)));
					
				break;
					
				default:
					printf( "\n\n\n\r !!!: the entered value is not correct, back to the menu") ;
				break;			
			}
		key =0;	
	}	
}