00001 /* ---------------------------------------------------------------------------- 00002 * SAM Software Package License 00003 * ---------------------------------------------------------------------------- 00004 * Copyright (c) 2011, Atmel Corporation 00005 * 00006 * All rights reserved. 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions are met: 00010 * 00011 * - Redistributions of source code must retain the above copyright notice, 00012 * this list of conditions and the disclaimer below. 00013 * 00014 * Atmel's name may not be used to endorse or promote products derived from 00015 * this software without specific prior written permission. 00016 * 00017 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR 00018 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00019 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 00020 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, 00021 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00022 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 00023 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00024 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00025 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 00026 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00027 * ---------------------------------------------------------------------------- 00028 */ 00029 00030 /** \addtogroup acc_module Working with ACC 00031 * \ingroup peripherals_module 00032 * The ACC driver provides the interface to configure and use the ACC 00033 * peripheral.\n 00034 * 00035 * It applies comparison on two inputs and gives a compare output. 00036 * 00037 * To Enable a ACC Comparison,the user has to follow these few steps: 00038 * <ul> 00039 * <li> Enable ACC peripheral clock by setting the corresponding bit in 00040 * PMC_PCER1 (PMC Peripheral Clock Enable Register 1) 00041 * </li> 00042 * <li> Reset the controller by asserting ACC_CR_SWRST in ACC_CR(ACC Control 00043 * Register) </li> 00044 * <li> Configure the mode as following steps: </li> 00045 * -# Select inputs for SELMINUS and SELPLUS in ACC_MR (ACC Mode Register). 00046 * -# Enable Analog Comparator by setting ACEN in ACC_MR. 00047 * -# Configure Edge Type to detect different compare output. 00048 * </li> 00049 * <li> Wait until the automatic mask period expires by polling MASK bit in 00050 * ACC_ISR. 00051 * </ul> 00052 * 00053 * For more accurate information, please look at the ACC section of the 00054 * Datasheet. 00055 * 00056 * Related files :\n 00057 * \ref acc.c\n 00058 * \ref acc.h\n 00059 */ 00060 /*@{*/ 00061 /*@}*/ 00062 /** 00063 * \file 00064 * 00065 * Implementation of Analog Comparator Controller (ACC). 00066 * 00067 */ 00068 /*---------------------------------------------------------------------------- 00069 * Headers 00070 *----------------------------------------------------------------------------*/ 00071 00072 #include "chip.h" 00073 00074 /*---------------------------------------------------------------------------- 00075 * Exported functions 00076 *----------------------------------------------------------------------------*/ 00077 00078 /** 00079 * \brief Initialize the ACC controller 00080 * 00081 * \param pAcc Pointer to an Acc instance. 00082 * \param idAcc ACC identifier 00083 * \param ucSelplus input connected to inp, 0~7 00084 * \param ucSelminus input connected to inm,0~7 00085 * \param wAc_en Analog comparator enabled/disabled 00086 * \param wEdge CF flag triggering mode 00087 * \param wInvert INVert comparator output,use pattern defined in the device 00088 * header file 00089 */ 00090 extern void ACC_Configure( Acc *pAcc, uint8_t idAcc, uint8_t ucSelplus, 00091 uint8_t ucSelminus, uint16_t wAc_en, uint16_t wEdge, uint16_t wInvert ) 00092 { 00093 /* Enable peripheral clock*/ 00094 PMC->PMC_PCER1 = 1 << (idAcc - 32) ; 00095 00096 /* Reset the controller */ 00097 pAcc->ACC_CR |= ACC_CR_SWRST ; 00098 00099 /* Write to the MR register */ 00100 ACC_CfgModeReg( pAcc, 00101 ( (ucSelplus<<ACC_MR_SELPLUS_Pos) & ACC_MR_SELPLUS_Msk ) | 00102 ( (ucSelminus<<ACC_MR_SELMINUS_Pos) & ACC_MR_SELMINUS_Msk ) | 00103 ( (wAc_en<<8) & ACC_MR_ACEN ) | 00104 ( (wEdge<<ACC_MR_EDGETYP_Pos) & ACC_MR_EDGETYP_Msk ) | 00105 ( (wInvert<<12) & ACC_MR_INV ) ) ; 00106 /* set hysteresis and current option*/ 00107 pAcc->ACC_ACR = (ACC_ACR_ISEL_HISP 00108 | ((0x01 << ACC_ACR_HYST_Pos) & ACC_ACR_HYST_Msk)); 00109 00110 /* Automatic Output Masking Period*/ 00111 while ( pAcc->ACC_ISR & (uint32_t)ACC_ISR_MASK ) ; 00112 } 00113 00114 /** 00115 * Return the Channel Converted Data 00116 * \param pAcc Pointer to an Acc instance. 00117 * \param ucSelplus input applied on ACC SELPLUS 00118 * \param ucSelminus input applied on ACC SELMINUS 00119 */ 00120 extern void ACC_SetComparisonPair( Acc *pAcc, uint8_t ucSelplus, uint8_t ucSelminus ) 00121 { 00122 uint32_t dwTemp ; 00123 00124 assert( ucSelplus < 8 && ucSelminus < 8 ) ; 00125 00126 dwTemp = pAcc->ACC_MR ; 00127 pAcc->ACC_MR = 00128 dwTemp & (uint32_t) ((~ACC_MR_SELMINUS_Msk) & (~ACC_MR_SELPLUS_Msk)); 00129 00130 pAcc->ACC_MR |= ( ((ucSelplus << ACC_MR_SELPLUS_Pos) & ACC_MR_SELPLUS_Msk) | 00131 ((ucSelminus << ACC_MR_SELMINUS_Pos) & ACC_MR_SELMINUS_Msk) ) ; 00132 } 00133 00134 /** 00135 * Return Comparison Result 00136 * \param pAcc Pointer to an Acc instance. 00137 * \param dwStatus value of ACC_ISR 00138 */ 00139 extern uint32_t ACC_GetComparisonResult( Acc *pAcc, uint32_t dwStatus ) 00140 { 00141 uint32_t dwTemp = pAcc->ACC_MR ; 00142 00143 if ( (dwTemp & ACC_MR_INV) == ACC_MR_INV ) { 00144 if ( dwStatus & ACC_ISR_SCO ) { 00145 return 0 ; /* inn>inp*/ 00146 } else { 00147 return 1 ;/* inp>inn*/ 00148 } 00149 } else { 00150 if ( dwStatus & ACC_ISR_SCO ) { 00151 return 1 ; /* inp>inn*/ 00152 } else { 00153 return 0 ;/* inn>inp*/ 00154 } 00155 } 00156 } 00157