/* ----------------------------------------------------------------------------
* 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;
}
}