1 /**************************************************************************//**
2 * @file eadc.c
3 * @version V2.00
4 * @brief EADC driver source file
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 * @copyright (C) 2021 Nuvoton Technology Corp. All rights reserved.
8 *****************************************************************************/
9 #include "NuMicro.h"
10
11 /** @addtogroup Standard_Driver Standard Driver
12 @{
13 */
14
15 /** @addtogroup EADC_Driver EADC Driver
16 @{
17 */
18
19 /** @addtogroup EADC_EXPORTED_FUNCTIONS EADC Exported Functions
20 @{
21 */
22
23 /**
24 * @brief This function make EADC_module be ready to convert.
25 * @param[in] eadc The pointer of the specified EADC module.
26 * @param[in] u32InputMode Decides the input mode.
27 * - \ref EADC_CTL_DIFFEN_SINGLE_END :Single end input mode.
28 * - \ref EADC_CTL_DIFFEN_DIFFERENTIAL :Differential input type.
29 * @retval 0 EADC operation OK.
30 * @retval EADC_TIMEOUT_ERR EADC operation abort due to timeout error.
31 * @retval EADC_CAL_ERR EADC has calibration error.
32 * @retval EADC_CLKDIV_ERR EADC clock frequency is configured error.
33 * @details This function is used to set analog input mode and enable A/D Converter.
34 * Before starting A/D conversion function, ADCEN bit (EADC_CTL[0]) should be set to 1.
35 * @note This API will reset and calibrate EADC if EADC never be calibrated after chip power on.
36 * @note This function retrun EADC_TIMEOUT_ERR if CALIF(CALSR[16]) is not set to 1.
37 */
EADC_Open(EADC_T * eadc,uint32_t u32InputMode)38 int32_t EADC_Open(EADC_T *eadc, uint32_t u32InputMode)
39 {
40 uint32_t u32Delay = SystemCoreClock >> 4;
41 uint32_t u32ClkSel0Backup, u32ClkDivBackup, u32PclkDivBackup, u32RegLockBackup = 0, u32Apb1Div;
42
43 eadc->CTL &= (~EADC_CTL_DIFFEN_Msk);
44
45 eadc->CTL |= (u32InputMode | EADC_CTL_ADCEN_Msk);
46
47 /* Do calibration for EADC to decrease the effect of electrical random noise. */
48 if ((eadc->CALSR & EADC_CALSR_CALIF_Msk) == 0)
49 {
50 /* Must reset ADC before ADC calibration */
51 eadc->CTL |= EADC_CTL_ADCRST_Msk;
52 while((eadc->CTL & EADC_CTL_ADCRST_Msk) == EADC_CTL_ADCRST_Msk)
53 {
54 if (--u32Delay == 0)
55 {
56 return EADC_TIMEOUT_ERR;
57 }
58 }
59
60 /* Registers backup */
61 u32ClkSel0Backup = CLK->CLKSEL0;
62 u32PclkDivBackup = CLK->PCLKDIV;
63
64 u32RegLockBackup = SYS_IsRegLocked();
65
66 /* Unlock protected registers */
67 SYS_UnlockReg();
68
69 /* Set EADC clock is less than 2*PCLK to do calibration correctly. */
70 if (eadc == EADC0)
71 {
72 u32ClkDivBackup = CLK->CLKDIV0;
73 CLK->CLKDIV0 = (CLK->CLKDIV0 & ~CLK_CLKDIV0_EADC0DIV_Msk) | (2 << CLK_CLKDIV0_EADC0DIV_Pos);
74 CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_EADC0SEL_Msk) | CLK_CLKSEL0_EADC0SEL_HCLK;
75 }
76 else if (eadc == EADC1)
77 {
78 u32ClkDivBackup = CLK->CLKDIV2;
79 CLK->CLKDIV2 = (CLK->CLKDIV2 & ~CLK_CLKDIV2_EADC1DIV_Msk) | (2 << CLK_CLKDIV2_EADC1DIV_Pos);
80 CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_EADC1SEL_Msk) | CLK_CLKSEL0_EADC1SEL_HCLK;
81 }
82 else if (eadc == EADC2)
83 {
84 u32ClkDivBackup = CLK->CLKDIV5;
85 CLK->CLKDIV5 = (CLK->CLKDIV5 & ~CLK_CLKDIV5_EADC2DIV_Msk) | (2 << CLK_CLKDIV5_EADC2DIV_Pos);
86 CLK->CLKSEL0 = (CLK->CLKSEL0 & ~CLK_CLKSEL0_EADC2SEL_Msk) | CLK_CLKSEL0_EADC2SEL_HCLK;
87 }
88 CLK->PCLKDIV = (CLK->PCLKDIV & ~CLK_PCLKDIV_APB1DIV_Msk);
89
90 eadc->CALSR |= EADC_CALSR_CALIF_Msk; /* Clear Calibration Finish Interrupt Flag */
91 eadc->CALCTL = (eadc->CALCTL & ~(0x000F0000))|0x00020000;
92 eadc->CALCTL |= EADC_CALCTL_CAL_Msk; /* Enable Calibration function */
93
94 u32Delay = SystemCoreClock >> 4;
95 while((eadc->CALSR & EADC_CALSR_CALIF_Msk) != EADC_CALSR_CALIF_Msk)
96 {
97 if (--u32Delay == 0)
98 {
99 return EADC_CAL_ERR;
100 }
101 }
102
103 /* Restore registers */
104 CLK->PCLKDIV = u32PclkDivBackup;
105 CLK->CLKSEL0 = u32ClkSel0Backup;
106 if (eadc == EADC0)
107 {
108 CLK->CLKDIV0 = u32ClkDivBackup;
109 }
110 else if (eadc == EADC1)
111 {
112 CLK->CLKDIV2 = u32ClkDivBackup;
113 }
114 else if (eadc == EADC2)
115 {
116 CLK->CLKDIV5 = u32ClkDivBackup;
117 }
118 if (u32RegLockBackup)
119 {
120 /* Lock protected registers */
121 SYS_LockReg();
122 }
123 }
124
125 /* Check EADC clock frequency must not faster than PCLK */
126 u32Apb1Div = (CLK->PCLKDIV & CLK_PCLKDIV_APB1DIV_Msk) >> CLK_PCLKDIV_APB1DIV_Pos;
127 if (eadc == EADC0)
128 {
129 if (u32Apb1Div > ((CLK->CLKDIV0 & CLK_CLKDIV0_EADC0DIV_Msk) >> CLK_CLKDIV0_EADC0DIV_Pos))
130 {
131 return EADC_CLKDIV_ERR;
132 }
133 }
134 else if (eadc == EADC1)
135 {
136 if (u32Apb1Div > ((CLK->CLKDIV2 & CLK_CLKDIV2_EADC1DIV_Msk) >> CLK_CLKDIV2_EADC1DIV_Pos))
137 {
138 return EADC_CLKDIV_ERR;
139 }
140 }
141 else if (eadc == EADC2)
142 {
143 if (u32Apb1Div > ((CLK->CLKDIV5 & CLK_CLKDIV5_EADC2DIV_Msk) >> CLK_CLKDIV5_EADC2DIV_Pos))
144 {
145 return EADC_CLKDIV_ERR;
146 }
147 }
148
149 return 0;
150 }
151
152 /**
153 * @brief Disable EADC_module.
154 * @param[in] eadc The pointer of the specified EADC module.
155 * @return None
156 * @details Clear ADCEN bit (EADC_CTL[0]) to disable A/D converter analog circuit power consumption.
157 */
EADC_Close(EADC_T * eadc)158 void EADC_Close(EADC_T *eadc)
159 {
160 eadc->CTL &= ~EADC_CTL_ADCEN_Msk;
161 }
162
163 /**
164 * @brief Configure the sample control logic module.
165 * @param[in] eadc The pointer of the specified EADC module.
166 * @param[in] u32ModuleNum Decides the sample module number, valid value are from 0 to 15.
167 * @param[in] u32TriggerSrc Decides the trigger source. Valid values are:
168 * - \ref EADC_SOFTWARE_TRIGGER : Disable trigger
169 * - \ref EADC_FALLING_EDGE_TRIGGER : STADC pin falling edge trigger
170 * - \ref EADC_RISING_EDGE_TRIGGER : STADC pin rising edge trigger
171 * - \ref EADC_FALLING_RISING_EDGE_TRIGGER : STADC pin both falling and rising edge trigger
172 * - \ref EADC_ADINT0_TRIGGER : EADC ADINT0 interrupt EOC pulse trigger
173 * - \ref EADC_ADINT1_TRIGGER : EADC ADINT1 interrupt EOC pulse trigger
174 * - \ref EADC_TIMER0_TRIGGER : Timer0 overflow pulse trigger
175 * - \ref EADC_TIMER1_TRIGGER : Timer1 overflow pulse trigger
176 * - \ref EADC_TIMER2_TRIGGER : Timer2 overflow pulse trigger
177 * - \ref EADC_TIMER3_TRIGGER : Timer3 overflow pulse trigger
178 * - \ref EADC_EPWM0TG0_TRIGGER : EPWM0TG0 trigger
179 * - \ref EADC_EPWM0TG1_TRIGGER : EPWM0TG1 trigger
180 * - \ref EADC_EPWM0TG2_TRIGGER : EPWM0TG2 trigger
181 * - \ref EADC_EPWM0TG3_TRIGGER : EPWM0TG3 trigger
182 * - \ref EADC_EPWM0TG4_TRIGGER : EPWM0TG4 trigger
183 * - \ref EADC_EPWM0TG5_TRIGGER : EPWM0TG5 trigger
184 * - \ref EADC_EPWM1TG0_TRIGGER : EPWM1TG0 trigger
185 * - \ref EADC_EPWM1TG1_TRIGGER : EPWM1TG1 trigger
186 * - \ref EADC_EPWM1TG2_TRIGGER : EPWM1TG2 trigger
187 * - \ref EADC_EPWM1TG3_TRIGGER : EPWM1TG3 trigger
188 * - \ref EADC_EPWM1TG4_TRIGGER : EPWM1TG4 trigger
189 * - \ref EADC_EPWM1TG5_TRIGGER : EPWM1TG5 trigger
190 * - \ref EADC_BPWM0TG_TRIGGER : BPWM0TG trigger
191 * - \ref EADC_BPWM1TG_TRIGGER : BPWM1TG trigger
192 * @param[in] u32Channel Specifies the sample module channel, valid value are from 0 to 15.
193 * @return None
194 * @details Each of ADC control logic modules 0~15 which is configurable for ADC converter channel EADC_CH0~15 and trigger source.
195 * sample module 16~18 is fixed for ADC channel 16, 17, 18 input sources as band-gap voltage, temperature sensor, and battery power (VBAT).
196 */
EADC_ConfigSampleModule(EADC_T * eadc,uint32_t u32ModuleNum,uint32_t u32TriggerSrc,uint32_t u32Channel)197 void EADC_ConfigSampleModule(EADC_T *eadc, \
198 uint32_t u32ModuleNum, \
199 uint32_t u32TriggerSrc, \
200 uint32_t u32Channel)
201 {
202 eadc->SCTL[u32ModuleNum] &= ~(EADC_SCTL_EXTFEN_Msk | EADC_SCTL_EXTREN_Msk | EADC_SCTL_TRGSEL_Msk | EADC_SCTL_CHSEL_Msk);
203 eadc->SCTL[u32ModuleNum] |= (u32TriggerSrc | u32Channel);
204 }
205
206
207 /**
208 * @brief Set trigger delay time.
209 * @param[in] eadc The pointer of the specified EADC module.
210 * @param[in] u32ModuleNum Decides the sample module number, valid value are from 0 to 15.
211 * @param[in] u32TriggerDelayTime Decides the trigger delay time, valid range are between 0~0xFF.
212 * @param[in] u32DelayClockDivider Decides the trigger delay clock divider. Valid values are:
213 * - \ref EADC_SCTL_TRGDLYDIV_DIVIDER_1 : Trigger delay clock frequency is ADC_CLK/1
214 * - \ref EADC_SCTL_TRGDLYDIV_DIVIDER_2 : Trigger delay clock frequency is ADC_CLK/2
215 * - \ref EADC_SCTL_TRGDLYDIV_DIVIDER_4 : Trigger delay clock frequency is ADC_CLK/4
216 * - \ref EADC_SCTL_TRGDLYDIV_DIVIDER_16 : Trigger delay clock frequency is ADC_CLK/16
217 * @return None
218 * @details User can configure the trigger delay time by setting TRGDLYCNT (EADC_SCTLn[15:8], n=0~15) and TRGDLYDIV (EADC_SCTLn[7:6], n=0~15).
219 * Trigger delay time = (u32TriggerDelayTime) x Trigger delay clock period.
220 */
EADC_SetTriggerDelayTime(EADC_T * eadc,uint32_t u32ModuleNum,uint32_t u32TriggerDelayTime,uint32_t u32DelayClockDivider)221 void EADC_SetTriggerDelayTime(EADC_T *eadc, \
222 uint32_t u32ModuleNum, \
223 uint32_t u32TriggerDelayTime, \
224 uint32_t u32DelayClockDivider)
225 {
226 eadc->SCTL[u32ModuleNum] &= ~(EADC_SCTL_TRGDLYDIV_Msk | EADC_SCTL_TRGDLYCNT_Msk);
227 eadc->SCTL[u32ModuleNum] |= ((u32TriggerDelayTime << EADC_SCTL_TRGDLYCNT_Pos) | u32DelayClockDivider);
228 }
229
230 /**
231 * @brief Set ADC extend sample time.
232 * @param[in] eadc The pointer of the specified EADC module.
233 * @param[in] u32ModuleNum Decides the sample module number, valid value are from 0 to 18.
234 * @param[in] u32ExtendSampleTime Decides the extend sampling time, the range is from 0~255 ADC clock. Valid value are from 0 to 0xFF.
235 * @return None
236 * @details When A/D converting at high conversion rate, the sampling time of analog input voltage may not enough if input channel loading is heavy,
237 * user can extend A/D sampling time after trigger source is coming to get enough sampling time.
238 */
EADC_SetExtendSampleTime(EADC_T * eadc,uint32_t u32ModuleNum,uint32_t u32ExtendSampleTime)239 void EADC_SetExtendSampleTime(EADC_T *eadc, uint32_t u32ModuleNum, uint32_t u32ExtendSampleTime)
240 {
241 eadc->SCTL[u32ModuleNum] &= ~EADC_SCTL_EXTSMPT_Msk;
242
243 eadc->SCTL[u32ModuleNum] |= (u32ExtendSampleTime << EADC_SCTL_EXTSMPT_Pos);
244
245 }
246
247 /*@}*/ /* end of group EADC_EXPORTED_FUNCTIONS */
248
249 /*@}*/ /* end of group EADC_Driver */
250
251 /*@}*/ /* end of group Standard_Driver */
252