00001 /* ---------------------------------------------------------------------------- */ 00002 /* Atmel Microcontroller Software Support */ 00003 /* SAM Software Package License */ 00004 /* ---------------------------------------------------------------------------- */ 00005 /* Copyright (c) 2015, Atmel Corporation */ 00006 /* */ 00007 /* All rights reserved. */ 00008 /* */ 00009 /* Redistribution and use in source and binary forms, with or without */ 00010 /* modification, are permitted provided that the following condition is met: */ 00011 /* */ 00012 /* - Redistributions of source code must retain the above copyright notice, */ 00013 /* this list of conditions and the disclaimer below. */ 00014 /* */ 00015 /* Atmel's name may not be used to endorse or promote products derived from */ 00016 /* this software without specific prior written permission. */ 00017 /* */ 00018 /* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR */ 00019 /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */ 00020 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE */ 00021 /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, */ 00022 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 00023 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ 00024 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */ 00025 /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ 00026 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */ 00027 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 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 #include "acc.h" 00074 00075 /*---------------------------------------------------------------------------- 00076 * Exported functions 00077 *----------------------------------------------------------------------------*/ 00078 00079 /** 00080 * \brief Initialize the ACC controller 00081 * 00082 * \param pAcc Pointer to an Acc instance. 00083 * \param idAcc ACC identifier 00084 * \param ucSelplus input connected to inp, 0~7 00085 * \param ucSelminus input connected to inm,0~7 00086 * \param wAc_en Analog comparator enabled/disabled 00087 * \param wEdge CF flag triggering mode 00088 * \param wInvert INVert comparator output,use pattern defined in the device 00089 * header file 00090 */ 00091 extern void ACC_Configure(Acc *pAcc, uint8_t idAcc, uint8_t ucSelplus, 00092 uint8_t ucSelminus, uint16_t wAc_en, uint16_t wEdge, uint16_t wInvert) 00093 { 00094 /* Enable peripheral clock*/ 00095 PMC->PMC_PCER1 = 1 << (idAcc - 32); 00096 00097 /* Reset the controller */ 00098 pAcc->ACC_CR |= ACC_CR_SWRST; 00099 00100 /* Write to the MR register */ 00101 ACC_CfgModeReg(pAcc, 00102 ((ucSelplus << ACC_MR_SELPLUS_Pos) & ACC_MR_SELPLUS_Msk) | 00103 ((ucSelminus << ACC_MR_SELMINUS_Pos) & ACC_MR_SELMINUS_Msk) | 00104 ((wAc_en << 8) & ACC_MR_ACEN) | 00105 ((wEdge << ACC_MR_EDGETYP_Pos) & ACC_MR_EDGETYP_Msk) | 00106 ((wInvert << 12) & ACC_MR_INV)); 00107 /* set hysteresis and current option*/ 00108 pAcc->ACC_ACR = (ACC_ACR_ISEL_HISP 00109 | ((0x01 << ACC_ACR_HYST_Pos) & ACC_ACR_HYST_Msk)); 00110 00111 /* Automatic Output Masking Period*/ 00112 while (pAcc->ACC_ISR & (uint32_t)ACC_ISR_MASK); 00113 } 00114 00115 /** 00116 * Return the Channel Converted Data 00117 * \param pAcc Pointer to an Acc instance. 00118 * \param ucSelplus input applied on ACC SELPLUS 00119 * \param ucSelminus input applied on ACC SELMINUS 00120 */ 00121 extern void ACC_SetComparisonPair(Acc *pAcc, uint8_t ucSelplus, 00122 uint8_t ucSelminus) 00123 { 00124 uint32_t dwTemp; 00125 00126 assert(ucSelplus < 8 && ucSelminus < 8); 00127 00128 dwTemp = pAcc->ACC_MR; 00129 pAcc->ACC_MR = 00130 dwTemp & (uint32_t) ((~ACC_MR_SELMINUS_Msk) & (~ACC_MR_SELPLUS_Msk)); 00131 00132 pAcc->ACC_MR |= (((ucSelplus << ACC_MR_SELPLUS_Pos) & ACC_MR_SELPLUS_Msk) | 00133 ((ucSelminus << ACC_MR_SELMINUS_Pos) & ACC_MR_SELMINUS_Msk)); 00134 } 00135 00136 /** 00137 * Return Comparison Result 00138 * \param pAcc Pointer to an Acc instance. 00139 * \param dwStatus value of ACC_ISR 00140 */ 00141 extern uint32_t ACC_GetComparisonResult(Acc *pAcc, uint32_t dwStatus) 00142 { 00143 uint32_t dwTemp = pAcc->ACC_MR; 00144 00145 if ((dwTemp & ACC_MR_INV) == ACC_MR_INV) { 00146 if (dwStatus & ACC_ISR_SCO) { 00147 return 0; /* inn>inp*/ 00148 } else { 00149 return 1;/* inp>inn*/ 00150 } 00151 } else { 00152 if (dwStatus & ACC_ISR_SCO) { 00153 return 1; /* inp>inn*/ 00154 } else { 00155 return 0;/* inn>inp*/ 00156 } 00157 } 00158 } 00159