1 /**************************************************************************//** 2 * @file acmp.c 3 * @version V1.0 4 * @brief M2L31 series Analog Comparator (ACMP) driver source file 5 * 6 * SPDX-License-Identifier: Apache-2.0 7 * @copyright (C) 2023 Nuvoton Technology Corp. All rights reserved. 8 *****************************************************************************/ 9 #include "NuMicro.h" 10 11 /** @addtogroup Standard_Driver Standard Driver 12 @{ 13 */ 14 15 /** @addtogroup ACMP_Driver ACMP Driver 16 @{ 17 */ 18 19 int32_t g_ACMP_i32ErrCode = 0; /*!< ACMP global error code */ 20 21 /** @addtogroup ACMP_EXPORTED_FUNCTIONS ACMP Exported Functions 22 @{ 23 */ 24 25 26 /** 27 * @brief Configure the specified ACMP module 28 * 29 * @param[in] acmp The pointer of the specified ACMP module 30 * @param[in] u32ChNum Comparator number. 31 * @param[in] u32NegSrc Comparator negative input selection. Including: 32 * - \ref ACMP_CTL_NEGSEL_PIN 33 * - \ref ACMP_CTL_NEGSEL_CRV 34 * - \ref ACMP_CTL_NEGSEL_VBG 35 * - \ref ACMP_CTL_NEGSEL_DAC0 36 * - \ref ACMP_CTL_NEGSEL_DAC1 37 * @param[in] u32HysSel The hysteresis function option. Including: 38 * - \ref ACMP_CTL_HYSTERESIS_40MV 39 * - \ref ACMP_CTL_HYSTERESIS_20MV 40 * - \ref ACMP_CTL_HYSTERESIS_DISABLE 41 * 42 * @return None 43 * 44 * @details Configure hysteresis function, select the source of negative input and enable analog comparator. 45 * @note This API will reset and calibrate ACMP if ACMP never be calibrated after chip power on. 46 */ ACMP_Open(ACMP_T * acmp,uint32_t u32ChNum,uint32_t u32NegSrc,uint32_t u32HysSel)47void ACMP_Open(ACMP_T *acmp, uint32_t u32ChNum, uint32_t u32NegSrc, uint32_t u32HysSel) 48 { 49 uint32_t u32Delay = SystemCoreClock; /* 1 second */ 50 51 g_ACMP_i32ErrCode = 0; 52 53 /* Do calibration for ACMP to decrease the effect of electrical random noise. */ 54 if (acmp == ACMP01) 55 { 56 if (((acmp->CALSR & ACMP_CALSR_DONE0_Msk) == 0) || ((acmp->CALSR & ACMP_CALSR_DONE1_Msk) == 0)) 57 { 58 /* Must reset ACMP before ACMP calibration */ 59 SYS->IPRST1 |= (SYS_IPRST1_ACMP01RST_Msk); 60 SYS->IPRST1 &= ~(SYS_IPRST1_ACMP01RST_Msk); 61 62 /* Calibration ACMP0 */ 63 acmp->CTL[0] |= ACMP_CTL_ACMPEN_Msk; 64 65 /* MUST enable CRV and set NEGSEL to CRV for ACMP calibration. */ 66 acmp->VREF = (ACMP_VREF_CRV0EN_Msk | ACMP_VREF_CRV0SSEL_Msk); 67 acmp->CTL[0] = (acmp->CTL[0] & ~(ACMP_CTL_NEGSEL_Msk)) | 68 (ACMP_CTL_NEGSEL_CRV); 69 70 acmp->CALCTL |= ACMP_CALCTL_CALTRG0_Msk; /* Start to calibration */ 71 u32Delay = SystemCoreClock; 72 while ((acmp->CALSR & ACMP_CALSR_DONE0_Msk) == 0) /* Wait calibration finish */ 73 { 74 if (--u32Delay == 0) 75 { 76 g_ACMP_i32ErrCode = ACMP_TIMEOUT_ERR; 77 break; 78 } 79 } 80 81 /* Calibration ACMP1 */ 82 acmp->CTL[1] |= ACMP_CTL_ACMPEN_Msk; 83 84 /* MUST enable CRV and set NEGSEL to CRV for ACMP calibration. */ 85 acmp->VREF = (ACMP_VREF_CRV1EN_Msk | ACMP_VREF_CRV1SSEL_Msk); 86 acmp->CTL[1] = (acmp->CTL[1] & ~(ACMP_CTL_NEGSEL_Msk)) | 87 (ACMP_CTL_NEGSEL_CRV); 88 89 acmp->CALCTL |= ACMP_CALCTL_CALTRG1_Msk; /* Start to calibration */ 90 u32Delay = SystemCoreClock; 91 while ((acmp->CALSR & ACMP_CALSR_DONE1_Msk) == 0) /* Wait calibration finish */ 92 { 93 if (--u32Delay == 0) 94 { 95 g_ACMP_i32ErrCode = ACMP_TIMEOUT_ERR; 96 break; 97 } 98 } 99 } 100 acmp->CTL[u32ChNum] = (acmp->CTL[u32ChNum] & (~(ACMP_CTL_NEGSEL_Msk | ACMP_CTL_HYSSEL_Msk))) | (u32NegSrc | u32HysSel | ACMP_CTL_ACMPEN_Msk); 101 } 102 103 if (acmp == ACMP2) 104 { 105 /* Do calibration for ACMP to decrease the effect of electrical random noise. */ 106 if ((acmp->CALSR & ACMP_CALSR_DONE2_Msk) == 0) 107 { 108 /* Must reset ACMP before ACMP calibration */ 109 SYS->IPRST3 |= (SYS_IPRST3_ACMP2RST_Msk); 110 SYS->IPRST3 &= ~(SYS_IPRST3_ACMP2RST_Msk); 111 112 /* Calibration ACMP0 */ 113 acmp->CTL[0] |= ACMP_CTL_ACMPEN_Msk; 114 115 /* MUST enable CRV and set NEGSEL to CRV for ACMP calibration. */ 116 acmp->VREF = (ACMP_VREF_CRV2EN_Msk | ACMP_VREF_CRV2SSEL_Msk); 117 acmp->CTL[0] = (acmp->CTL[0] & ~(ACMP_CTL_NEGSEL_Msk)) | 118 (ACMP_CTL_NEGSEL_CRV); 119 120 acmp->CALCTL |= ACMP_CALCTL_CALTRG2_Msk; /* Start to calibration */ 121 u32Delay = SystemCoreClock; 122 while ((acmp->CALSR & ACMP_CALSR_DONE2_Msk) == 0) /* Wait calibration finish */ 123 { 124 if (--u32Delay == 0) 125 { 126 g_ACMP_i32ErrCode = ACMP_TIMEOUT_ERR; 127 break; 128 } 129 } 130 } 131 acmp->CTL[0] = (acmp->CTL[u32ChNum] & (~(ACMP_CTL_NEGSEL_Msk | ACMP_CTL_HYSSEL_Msk))) | (u32NegSrc | u32HysSel | ACMP_CTL_ACMPEN_Msk); 132 } 133 } 134 135 /** 136 * @brief Close analog comparator 137 * 138 * @param[in] acmp The pointer of the specified ACMP module 139 * @param[in] u32ChNum Comparator number. 140 * 141 * @return None 142 * 143 * @details This function will clear ACMPEN bit of ACMP_CTL register to disable analog comparator. 144 */ ACMP_Close(ACMP_T * acmp,uint32_t u32ChNum)145void ACMP_Close(ACMP_T *acmp, uint32_t u32ChNum) 146 { 147 if (acmp == ACMP01) 148 { 149 acmp->CTL[u32ChNum] &= (~ACMP_CTL_ACMPEN_Msk); 150 } 151 152 if (acmp == ACMP2) 153 { 154 acmp->CTL[0] &= (~ACMP_CTL_ACMPEN_Msk); 155 } 156 } 157 158 /*@}*/ /* end of group ACMP_EXPORTED_FUNCTIONS */ 159 160 /*@}*/ /* end of group ACMP_Driver */ 161 162 /*@}*/ /* end of group Standard_Driver */ 163 164 /*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/ 165