1 /*
2 * Copyright (c) 2021 Bestechnic (Shanghai) Co., Ltd. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "plat_addr_map.h"
16
17 #if !defined(GPADC_CHIP_SPECIFIC) && !defined(CHIP_SUBSYS_SENS)
18
19 #include "stddef.h"
20 #include "cmsis_nvic.h"
21 #include "hal_gpadc.h"
22 #include "hal_trace.h"
23 #include "hal_analogif.h"
24 #include "pmu.h"
25
26 #define HAL_GPADC_TRACE(n, s, ...) //TRACE(n, s, ##__VA_ARGS__)
27
28 #define VBAT_DIV_ALWAYS_ON
29
30 #define gpadc_reg_read(reg,val) pmu_read(reg,val)
31 #define gpadc_reg_write(reg,val) pmu_write(reg,val)
32
33 #ifdef GPADC_DYNAMIC_DATA_BITS
34 #define GPADC_VALUE_BITS gpadc_data_bits
35 #elif defined(CHIP_BEST1305) || defined(CHIP_BEST2002) || defined(CHIP_BEST2003)
36 #define GPADC_VALUE_BITS 16
37 #else
38 #define GPADC_VALUE_BITS 10
39 #endif
40
41 #if 0
42 #elif defined(CHIP_BEST1305) || \
43 defined(CHIP_BEST1400) || defined(CHIP_BEST1402) || \
44 defined(CHIP_BEST1501) || defined(CHIP_BEST1600) || \
45 defined(CHIP_BEST1501SIMU) || defined(CHIP_BEST1600SIMU) || \
46 defined(CHIP_BEST2000) || defined(CHIP_BEST2001) || defined(CHIP_BEST2002) || defined(CHIP_BEST2003) || \
47 defined(CHIP_BEST2300) || defined(CHIP_BEST2300A) || defined(CHIP_BEST2300P) || \
48 defined(CHIP_BEST3001) || defined(CHIP_BEST3005)
49
50 #if defined(CHIP_BEST1305) || \
51 defined(CHIP_BEST1400) || defined(CHIP_BEST1402) || \
52 defined(CHIP_BEST2001) || defined(CHIP_BEST2002) || defined(CHIP_BEST2003)
53
54 enum GPADC_REG_T {
55 GPADC_REG_VBAT_EN = 0x02,
56 GPADC_REG_INTVL_EN = 0x18,
57 GPADC_REG_INTVL_VAL = 0x1C,
58 GPADC_REG_START = 0x4F,
59 GPADC_REG_CH_EN = 0x1D,
60 GPADC_REG_INT_MASK = 0x1F,
61 GPADC_REG_INT_EN = 0x20,
62 GPADC_REG_INT_RAW_STS = 0x50,
63 GPADC_REG_INT_MSKED_STS = 0x51,
64 GPADC_REG_INT_CLR = 0x51,
65 GPADC_REG_CH0_DATA = 0x56,
66 };
67
68 #else
69
70 enum GPADC_REG_T {
71 GPADC_REG_VBAT_EN = 0x02,
72 GPADC_REG_INTVL_EN = 0x1F,
73 GPADC_REG_INTVL_VAL = 0x23,
74 GPADC_REG_START = 0x4F,
75 GPADC_REG_CH_EN = 0x24,
76 GPADC_REG_INT_MASK = 0x26,
77 GPADC_REG_INT_EN = 0x27,
78 #if defined(CHIP_BEST1501) || defined(CHIP_BEST1600) || defined(CHIP_BEST1501SIMU) || \
79 defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A)
80 GPADC_REG_INT_RAW_STS = 0x52,
81 GPADC_REG_INT_MSKED_STS = 0x53,
82 GPADC_REG_INT_CLR = 0x51,
83 #else
84 GPADC_REG_INT_RAW_STS = 0x50,
85 GPADC_REG_INT_MSKED_STS = 0x51,
86 GPADC_REG_INT_CLR = 0x51,
87 #endif
88 GPADC_REG_CH0_DATA = 0x56,
89 };
90
91 #endif
92
93 // GPADC_REG_VBAT_EN
94 #define REG_PU_VBAT_DIV (1 << 15)
95
96 // GPADC_REG_INTVL_EN
97 #define GPADC_INTERVAL_MODE (1 << 12)
98
99 // GPADC_REG_START
100 #define GPADC_START (1 << 5)
101 #define KEY_START (1 << 4)
102
103 // GPADC_REG_CH_EN
104 #define CHAN_EN_REG_SHIFT 0
105 #define CHAN_EN_REG_MASK (0xFF << CHAN_EN_REG_SHIFT)
106 #define CHAN_EN_REG(n) BITFIELD_VAL(CHAN_EN_REG, n)
107
108 // GPADC_REG_INT_MASK
109 #define KEY_ERR1_INTR_MSK (1 << 12)
110 #define KEY_ERR0_INTR_MSK (1 << 11)
111 #define KEY_PRESS_INTR_MSK (1 << 10)
112 #define KEY_RELEASE_INTR_MSK (1 << 9)
113 #define SAMPLE_DONE_INTR_MSK (1 << 8)
114 #define CHAN_DATA_INTR_MSK_SHIFT 0
115 #define CHAN_DATA_INTR_MSK_MASK (0xFF << CHAN_DATA_INTR_MSK_SHIFT)
116 #define CHAN_DATA_INTR_MSK(n) BITFIELD_VAL(CHAN_DATA_INTR_MSK, n)
117
118 // GPADC_REG_INT_EN
119 #define KEY_ERR1_INTR_EN (1 << 12)
120 #define KEY_ERR0_INTR_EN (1 << 11)
121 #define KEY_PRESS_INTR_EN (1 << 10)
122 #define KEY_RELEASE_INTR_EN (1 << 9)
123 #define SAMPLE_DONE_INTR_EN (1 << 8)
124 #define CHAN_DATA_INTR_EN_SHIFT 0
125 #define CHAN_DATA_INTR_EN_MASK (0xFF << CHAN_DATA_INTR_EN_SHIFT)
126 #define CHAN_DATA_INTR_EN(n) BITFIELD_VAL(CHAN_DATA_INTR_EN, n)
127
128 // GPADC_REG_INT_RAW_STS
129 #define KEY_ERR1_INTR (1 << 12)
130 #define KEY_ERR0_INTR (1 << 11)
131 #define KEY_PRESS_INTR (1 << 10)
132 #define KEY_RELEASE_INTR (1 << 9)
133 #define SAMPLE_PERIOD_DONE_INTR (1 << 8)
134 #define CHAN_DATA_VALID_INTR_SHIFT 0
135 #define CHAN_DATA_VALID_INTR_MASK (0xFF << CHAN_DATA_VALID_INTR_SHIFT)
136 #define CHAN_DATA_VALID_INTR(n) BITFIELD_VAL(CHAN_DATA_VALID_INTR, n)
137
138 // GPADC_REG_INT_MSKED_STS
139 #define KEY_ERR1_INTR_MSKED (1 << 12)
140 #define KEY_ERR0_INTR_MSKED (1 << 11)
141 #define KEY_PRESS_INTR_MSKED (1 << 10)
142 #define KEY_RELEASE_INTR_MSKED (1 << 9)
143 #define SAMPLE_DONE_INTR_MSKED (1 << 8)
144 #define CHAN_DATA_INTR_MSKED_SHIFT 0
145 #define CHAN_DATA_INTR_MSKED_MASK (0xFF << CHAN_DATA_INTR_MSKED_SHIFT)
146 #define CHAN_DATA_INTR_MSKED(n) BITFIELD_VAL(CHAN_DATA_INTR_MSKED, n)
147
148 // GPADC_REG_INT_CLR
149 #define KEY_ERR1_INTR_CLR (1 << 12)
150 #define KEY_ERR0_INTR_CLR (1 << 11)
151 #define KEY_PRESS_INTR_CLR (1 << 10)
152 #define KEY_RELEASE_INTR_CLR (1 << 9)
153 #define SAMPLE_DONE_INTR_CLR (1 << 8)
154 #define CHAN_DATA_INTR_CLR_SHIFT 0
155 #define CHAN_DATA_INTR_CLR_MASK (0xFF << CHAN_DATA_INTR_CLR_SHIFT)
156 #define CHAN_DATA_INTR_CLR(n) BITFIELD_VAL(CHAN_DATA_INTR_CLR, n)
157
158 // GPADC_REG_CH0_DATA
159 #define DATA_CHAN0_SHIFT 0
160 #define DATA_CHAN0_MASK (((1 << GPADC_VALUE_BITS) - 1) << DATA_CHAN0_SHIFT)
161 #define DATA_CHAN0(n) BITFIELD_VAL(DATA_CHAN0, n)
162
163 #elif defined(CHIP_BEST1000)
164
165 enum GPADC_REG_T {
166 GPADC_REG_VBAT_EN = 0x45,
167 GPADC_REG_INTVL_EN = 0x60,
168 GPADC_REG_INTVL_VAL = 0x64,
169 GPADC_REG_START = 0x65,
170 GPADC_REG_CH_EN = 0x65,
171 GPADC_REG_INT_MASK = 0x67,
172 GPADC_REG_INT_EN = 0x68,
173 GPADC_REG_INT_RAW_STS = 0x69,
174 GPADC_REG_INT_MSKED_STS = 0x6A,
175 GPADC_REG_INT_CLR = 0x6A,
176 GPADC_REG_CH0_DATA = 0x78,
177 };
178
179 // GPADC_REG_VBAT_EN
180 #define REG_PU_VBAT_DIV (1 << 0)
181
182 // GPADC_REG_INTVL_EN
183 #define GPADC_INTERVAL_MODE (1 << 12)
184
185 // GPADC_REG_START
186 #define KEY_START (1 << 9)
187 #define GPADC_START (1 << 8)
188
189 // GPADC_REG_CH_EN
190 #define CHAN_EN_REG_SHIFT 0
191 #define CHAN_EN_REG_MASK (0xFF << CHAN_EN_REG_SHIFT)
192 #define CHAN_EN_REG(n) BITFIELD_VAL(CHAN_EN_REG, n)
193
194 // GPADC_REG_INT_MASK
195 #define KEY_ERR1_INTR_MSK (1 << 12)
196 #define KEY_ERR0_INTR_MSK (1 << 11)
197 #define KEY_PRESS_INTR_MSK (1 << 10)
198 #define KEY_RELEASE_INTR_MSK (1 << 9)
199 #define SAMPLE_DONE_INTR_MSK (1 << 8)
200 #define CHAN_DATA_INTR_MSK_SHIFT 0
201 #define CHAN_DATA_INTR_MSK_MASK (0xFF << CHAN_DATA_INTR_MSK_SHIFT)
202 #define CHAN_DATA_INTR_MSK(n) BITFIELD_VAL(CHAN_DATA_INTR_MSK, n)
203
204 // GPADC_REG_INT_EN
205 #define KEY_ERR1_INTR_EN (1 << 12)
206 #define KEY_ERR0_INTR_EN (1 << 11)
207 #define KEY_PRESS_INTR_EN (1 << 10)
208 #define KEY_RELEASE_INTR_EN (1 << 9)
209 #define SAMPLE_DONE_INTR_EN (1 << 8)
210 #define CHAN_DATA_INTR_EN_SHIFT 0
211 #define CHAN_DATA_INTR_EN_MASK (0xFF << CHAN_DATA_INTR_EN_SHIFT)
212 #define CHAN_DATA_INTR_EN(n) BITFIELD_VAL(CHAN_DATA_INTR_EN, n)
213
214 // GPADC_REG_INT_RAW_STS
215 #define KEY_ERR1_INTR (1 << 12)
216 #define KEY_ERR0_INTR (1 << 11)
217 #define KEY_PRESS_INTR (1 << 10)
218 #define KEY_RELEASE_INTR (1 << 9)
219 #define SAMPLE_PERIOD_DONE_INTR (1 << 8)
220 #define CHAN_DATA_VALID_INTR_SHIFT 0
221 #define CHAN_DATA_VALID_INTR_MASK (0xFF << CHAN_DATA_VALID_INTR_SHIFT)
222 #define CHAN_DATA_VALID_INTR(n) BITFIELD_VAL(CHAN_DATA_VALID_INTR, n)
223
224 // GPADC_REG_INT_MSKED_STS
225 #define KEY_ERR1_INTR_MSKED (1 << 12)
226 #define KEY_ERR0_INTR_MSKED (1 << 11)
227 #define KEY_PRESS_INTR_MSKED (1 << 10)
228 #define KEY_RELEASE_INTR_MSKED (1 << 9)
229 #define SAMPLE_DONE_INTR_MSKED (1 << 8)
230 #define CHAN_DATA_INTR_MSKED_SHIFT 0
231 #define CHAN_DATA_INTR_MSKED_MASK (0xFF << CHAN_DATA_INTR_MSKED_SHIFT)
232 #define CHAN_DATA_INTR_MSKED(n) BITFIELD_VAL(CHAN_DATA_INTR_MSKED, n)
233
234 // GPADC_REG_INT_CLR
235 #define KEY_ERR1_INTR_CLR (1 << 12)
236 #define KEY_ERR0_INTR_CLR (1 << 11)
237 #define KEY_PRESS_INTR_CLR (1 << 10)
238 #define KEY_RELEASE_INTR_CLR (1 << 9)
239 #define SAMPLE_DONE_INTR_CLR (1 << 8)
240 #define CHAN_DATA_INTR_CLR_SHIFT 0
241 #define CHAN_DATA_INTR_CLR_MASK (0xFF << CHAN_DATA_INTR_CLR_SHIFT)
242 #define CHAN_DATA_INTR_CLR(n) BITFIELD_VAL(CHAN_DATA_INTR_CLR, n)
243
244 // GPADC_REG_CH0_DATA
245 #define DATA_CHAN0_SHIFT 0
246 #define DATA_CHAN0_MASK (((1 << GPADC_VALUE_BITS) - 1) << DATA_CHAN0_SHIFT)
247 #define DATA_CHAN0(n) BITFIELD_VAL(DATA_CHAN0, n)
248
249 #else
250 #error "Please update GPADC register definitions"
251 #endif
252
253 // Battery voltage = gpadc voltage * 4
254 // Range 0~2V
255 #define HAL_GPADC_MVOLT_A 800
256 #define HAL_GPADC_MVOLT_B 1050
257 #if (GPADC_VALUE_BITS == 16)
258 #if defined(CHIP_BEST2002) || defined(CHIP_BEST2003)
259 #define HAL_GPADC_CALIB_DEFAULT_A 0x3789
260 #define HAL_GPADC_CALIB_DEFAULT_B 0x4950
261 #else
262 #define HAL_GPADC_CALIB_DEFAULT_A 0x3E60
263 #define HAL_GPADC_CALIB_DEFAULT_B 0x5150
264 #endif
265 #else
266 #if !defined(GPADC_DYNAMIC_DATA_BITS) && (GPADC_VALUE_BITS < 10 || GPADC_VALUE_BITS > 16)
267 #error "GPADC value bits not in range"
268 #endif
269 #define HAL_GPADC_CALIB_DEFAULT_A (428 << (GPADC_VALUE_BITS - 10))
270 #define HAL_GPADC_CALIB_DEFAULT_B (565 << (GPADC_VALUE_BITS - 10))
271 #endif
272
273 #if defined(__FPU_USED) && (__FPU_USED == 1)
274 typedef float ADC_COEF_T;
275 #define ADC_CALC_FACTOR 1
276 #else
277 typedef int32_t ADC_COEF_T;
278 #define ADC_CALC_FACTOR 1000
279 #endif
280
281 #ifdef GPADC_DYNAMIC_DATA_BITS
282 static uint8_t gpadc_data_bits;
283 #endif
284
285 static ADC_COEF_T g_adcSlope = 0;
286 static ADC_COEF_T g_adcIntcpt = 0;
287 #ifdef PMU_EFUSE_PAGE_GPADC_CALI
288 static ADC_COEF_T g_adcSlope_1v = 0;
289 #define HAL_GPADC_CALIB_DEFAULT_1V 0x488F
290 #endif
291 static bool gpadc_irq_enabled = false;
292 static bool adckey_irq_enabled = false;
293 static bool irq_enabled = false;
294 static bool g_adcCalibrated = false;
295 static HAL_GPADC_EVENT_CB_T gpadc_event_cb[HAL_GPADC_CHAN_QTY];
296 static enum HAL_GPADC_ATP_T gpadc_atp[HAL_GPADC_CHAN_QTY];
297 static uint16_t gpadc_chan_en;
298 static uint16_t gpadc_irq_mask;
299
hal_gpadc_get_all_masked_irq(void)300 static uint16_t hal_gpadc_get_all_masked_irq(void)
301 {
302 uint16_t all;
303
304 all = KEY_ERR1_INTR_MSKED | KEY_ERR0_INTR_MSKED | KEY_PRESS_INTR_MSKED | KEY_RELEASE_INTR_MSKED |
305 SAMPLE_DONE_INTR_MSKED | CHAN_DATA_INTR_MSKED_MASK;
306 return all;
307 }
308
hal_gpadc_get_cur_masked_irq(void)309 static uint16_t hal_gpadc_get_cur_masked_irq(void)
310 {
311 #if (KEY_ERR1_INTR_MSKED != KEY_ERR1_INTR_MSK) || \
312 (KEY_ERR0_INTR_MSKED != KEY_ERR0_INTR_MSK) || \
313 (KEY_PRESS_INTR_MSKED != KEY_PRESS_INTR_MSK) || \
314 (KEY_RELEASE_INTR_MSKED != KEY_RELEASE_INTR_MSK) || \
315 (SAMPLE_DONE_INTR_MSKED != SAMPLE_DONE_INTR_MSK) || \
316 (CHAN_DATA_INTR_MSKED_MASK != CHAN_DATA_INTR_MSK_MASK)
317 #error "GPADC IRQ MASKED STS != IRQ MASK"
318 #endif
319
320 uint16_t all = hal_gpadc_get_all_masked_irq();
321 return (all & gpadc_irq_mask);
322 }
323
hal_gpadc_masked_irq_valid(uint16_t irq)324 int hal_gpadc_masked_irq_valid(uint16_t irq)
325 {
326 uint16_t masked = hal_gpadc_get_cur_masked_irq();
327 irq &= masked;
328 return (irq ? true: false);
329 }
330
hal_gpadc_filter_out_unmasked_irq(uint16_t irq)331 uint16_t hal_gpadc_filter_out_unmasked_irq(uint16_t irq)
332 {
333 uint16_t all = hal_gpadc_get_all_masked_irq();
334 uint16_t masked = hal_gpadc_get_cur_masked_irq();
335 irq &= ((~all) | masked);
336 return irq;
337 }
338
hal_gpadc_get_min_atp(void)339 static enum HAL_GPADC_ATP_T hal_gpadc_get_min_atp(void)
340 {
341 enum HAL_GPADC_CHAN_T ch;
342 enum HAL_GPADC_ATP_T atp = HAL_GPADC_ATP_NULL;
343
344 for (ch = HAL_GPADC_CHAN_0; ch < HAL_GPADC_CHAN_QTY; ch++) {
345 if (gpadc_atp[ch] != HAL_GPADC_ATP_NULL) {
346 if (atp == HAL_GPADC_ATP_NULL ||
347 (uint32_t)gpadc_atp[ch] < (uint32_t)atp) {
348 atp = gpadc_atp[ch];
349 }
350 }
351 }
352
353 return atp;
354 }
355
hal_gpadc_update_atp(void)356 static void hal_gpadc_update_atp(void)
357 {
358 enum HAL_GPADC_ATP_T atp;
359 uint16_t val;
360
361 atp = hal_gpadc_get_min_atp();
362
363 if (atp == HAL_GPADC_ATP_NULL || atp == HAL_GPADC_ATP_ONESHOT) {
364 gpadc_reg_read(GPADC_REG_INTVL_EN, &val);
365 val &= ~GPADC_INTERVAL_MODE;
366 gpadc_reg_write(GPADC_REG_INTVL_EN, val);
367 } else {
368 gpadc_reg_read(GPADC_REG_INTVL_EN, &val);
369 val |= GPADC_INTERVAL_MODE;
370 gpadc_reg_write(GPADC_REG_INTVL_EN, val);
371 val = atp * 1000 / 1024;
372 gpadc_reg_write(GPADC_REG_INTVL_VAL, val);
373 }
374 }
375
hal_gpadc_adc2volt_calib(void)376 static int hal_gpadc_adc2volt_calib(void)
377 {
378 ADC_COEF_T y1, y2, x1, x2;
379 unsigned short efuse_a = 0;
380 unsigned short efuse_b = 0;
381
382 if (!g_adcCalibrated)
383 {
384 y1 = (ADC_COEF_T)HAL_GPADC_MVOLT_A;
385 y2 = (ADC_COEF_T)HAL_GPADC_MVOLT_B;
386
387 pmu_get_efuse(PMU_EFUSE_PAGE_BATTER_LV, &efuse_a);
388
389 x1 = (ADC_COEF_T)(efuse_a > 0 ? efuse_a : HAL_GPADC_CALIB_DEFAULT_A);
390
391 pmu_get_efuse(PMU_EFUSE_PAGE_BATTER_HV, &efuse_b);
392 x2 = (ADC_COEF_T)(efuse_b > 0 ? efuse_b : HAL_GPADC_CALIB_DEFAULT_B);
393
394 g_adcSlope = (y2 - y1) * ADC_CALC_FACTOR / (x2 - x1);
395 g_adcIntcpt = ((y1 * x2) - (x1 * y2)) / ((x2 - x1));
396 g_adcCalibrated = true;
397
398 TRACE(7,"%s efuse:%d/%d LV=%d, HV=%d, Slope:%d Intcpt:%d", __func__,
399 efuse_a, efuse_b, (int32_t)x1, (int32_t)x2, (int32_t)g_adcSlope, (int32_t)g_adcIntcpt);
400
401 #ifdef PMU_EFUSE_PAGE_GPADC_CALI
402 ADC_COEF_T voltage;
403 pmu_get_efuse(PMU_EFUSE_PAGE_GPADC_CALI, &efuse_a);
404 x1 = (ADC_COEF_T)((HAL_GPADC_CALIB_DEFAULT_1V - 0x200 < efuse_a && efuse_a < HAL_GPADC_CALIB_DEFAULT_1V + 0x200) ? efuse_a : HAL_GPADC_CALIB_DEFAULT_1V);
405
406 voltage = (g_adcSlope * x1) + (g_adcIntcpt * ADC_CALC_FACTOR);
407 g_adcSlope_1v = voltage / 1000;
408 TRACE(7,"%s efuse cali 1v:%d, Slope:%d", __func__, efuse_a, (int32_t)g_adcSlope_1v);
409 #endif
410 }
411
412 return 0;
413 }
414
hal_gpadc_adc2volt(uint16_t gpadcVal)415 static HAL_GPADC_MV_T hal_gpadc_adc2volt(uint16_t gpadcVal)
416 {
417 int32_t voltage;
418
419 hal_gpadc_adc2volt_calib();
420 if (gpadcVal == HAL_GPADC_BAD_VALUE)
421 {
422 // Bad values from the GPADC are still Bad Values
423 // for the voltage-speaking user.
424 return HAL_GPADC_BAD_VALUE;
425 }
426 else
427 {
428 #ifdef PMU_EFUSE_PAGE_GPADC_CALI
429 voltage = (int32_t)((g_adcSlope * gpadcVal) + (g_adcIntcpt * ADC_CALC_FACTOR));
430 voltage = (int32_t)((ADC_COEF_T)voltage / g_adcSlope_1v);
431 #else
432 voltage = (int32_t)(((g_adcSlope * gpadcVal) / ADC_CALC_FACTOR) + (g_adcIntcpt));
433 #endif
434 return (voltage < 0) ? 0 : voltage;
435 }
436 }
437
438 #ifdef PMU_IRQ_UNIFIED
439 #define GPADC_IRQ_HDLR_PARAM uint16_t irq_status
440 #else
441 #define GPADC_IRQ_HDLR_PARAM void
442 #endif
hal_gpadc_irq_handler(GPADC_IRQ_HDLR_PARAM)443 static void hal_gpadc_irq_handler(GPADC_IRQ_HDLR_PARAM)
444 {
445 uint32_t lock;
446 enum HAL_GPADC_CHAN_T ch;
447 unsigned short read_val;
448 uint16_t adc_val;
449 HAL_GPADC_MV_T volt;
450
451 #ifdef PMU_IRQ_UNIFIED
452 irq_status &= hal_gpadc_get_cur_masked_irq();
453 #else
454 unsigned short irq_status;
455
456 gpadc_reg_read(GPADC_REG_INT_MSKED_STS, &irq_status);
457 irq_status &= hal_gpadc_get_cur_masked_irq();
458 gpadc_reg_write(GPADC_REG_INT_CLR, irq_status);
459 #endif
460
461 if (irq_status & CHAN_DATA_INTR_MSKED((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6))) {
462 for (ch = HAL_GPADC_CHAN_0; ch < HAL_GPADC_CHAN_QTY; ch++) {
463 if (irq_status & CHAN_DATA_INTR_MSKED(1<<ch)) {
464 switch (ch) {
465 case HAL_GPADC_CHAN_BATTERY:
466 case HAL_GPADC_CHAN_0:
467 case HAL_GPADC_CHAN_2:
468 case HAL_GPADC_CHAN_3:
469 case HAL_GPADC_CHAN_4:
470 case HAL_GPADC_CHAN_5:
471 case HAL_GPADC_CHAN_6:
472 gpadc_reg_read(GPADC_REG_CH0_DATA + ch, &adc_val);
473 adc_val = GET_BITFIELD(adc_val, DATA_CHAN0);
474 volt = hal_gpadc_adc2volt(adc_val);
475 if (gpadc_event_cb[ch]) {
476 gpadc_event_cb[ch](adc_val, volt);
477 }
478 if (gpadc_atp[ch] == HAL_GPADC_ATP_NULL || gpadc_atp[ch] == HAL_GPADC_ATP_ONESHOT) {
479 lock = int_lock();
480
481 #ifndef VBAT_DIV_ALWAYS_ON
482 if (ch == HAL_GPADC_CHAN_BATTERY) {
483 gpadc_reg_read(GPADC_REG_VBAT_EN, &read_val);
484 read_val &= ~REG_PU_VBAT_DIV;
485 gpadc_reg_write(GPADC_REG_VBAT_EN, read_val);
486 }
487 #endif
488
489 // Int mask
490 gpadc_reg_read(GPADC_REG_INT_MASK, &read_val);
491 read_val &= ~CHAN_DATA_INTR_MSK(1<<ch);
492 gpadc_reg_write(GPADC_REG_INT_MASK, read_val);
493 gpadc_irq_mask = read_val;
494
495 // Int enable
496 gpadc_reg_read(GPADC_REG_INT_EN, &read_val);
497 read_val &= ~CHAN_DATA_INTR_EN(1<<ch);
498 gpadc_reg_write(GPADC_REG_INT_EN, read_val);
499
500 // Channel enable
501 gpadc_reg_read(GPADC_REG_CH_EN, &read_val);
502 read_val &= ~CHAN_EN_REG(1<<ch);
503 gpadc_reg_write(GPADC_REG_CH_EN, read_val);
504 gpadc_chan_en = read_val;
505
506 int_unlock(lock);
507 }
508 break;
509 default:
510 break;
511 }
512 }
513 }
514 }
515
516 // Disable GPADC (GPADC_START will be cleared automatically unless in interval mode)
517 lock = int_lock();
518 if ((gpadc_chan_en & CHAN_EN_REG((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6))) == 0) {
519 gpadc_reg_read(GPADC_REG_START, &read_val);
520 read_val &= ~GPADC_START;
521 gpadc_reg_write(GPADC_REG_START, read_val);
522 #ifdef DCDC_CLOCK_CONTROL
523 hal_cmu_dcdc_clock_disable(HAL_CMU_DCDC_CLOCK_USER_GPADC);
524 #endif
525 }
526 int_unlock(lock);
527
528 if (irq_status & (CHAN_DATA_INTR_MSKED(1<<7)|KEY_RELEASE_INTR_MSKED|KEY_PRESS_INTR_MSKED|KEY_ERR0_INTR_MSKED|KEY_ERR1_INTR_MSKED)) {
529 if (gpadc_event_cb[HAL_GPADC_CHAN_ADCKEY]) {
530 enum HAL_ADCKEY_IRQ_STATUS_T adckey_irq;
531
532 adckey_irq = 0;
533 if (irq_status & KEY_RELEASE_INTR_MSKED) {
534 adckey_irq |= HAL_ADCKEY_RELEASED;
535 }
536 if (irq_status & KEY_PRESS_INTR_MSKED) {
537 adckey_irq |= HAL_ADCKEY_PRESSED;
538 }
539 if (irq_status & KEY_ERR0_INTR_MSKED) {
540 adckey_irq |= HAL_ADCKEY_ERR0;
541 }
542 if (irq_status & KEY_ERR1_INTR_MSKED) {
543 adckey_irq |= HAL_ADCKEY_ERR1;
544 }
545
546 if (irq_status & CHAN_DATA_INTR_MSKED(1<<7)) {
547 adckey_irq |= HAL_ADCKEY_ADC_VALID;
548
549 lock = int_lock();
550
551 // Int mask
552 gpadc_reg_read(GPADC_REG_INT_MASK, &read_val);
553 read_val &= ~CHAN_DATA_INTR_MSK(1<<7);
554 gpadc_reg_write(GPADC_REG_INT_MASK, read_val);
555 gpadc_irq_mask = read_val;
556
557 // Int enable
558 gpadc_reg_read(GPADC_REG_INT_EN, &read_val);
559 read_val &= ~CHAN_DATA_INTR_EN(1<<7);
560 gpadc_reg_write(GPADC_REG_INT_EN, read_val);
561
562 int_unlock(lock);
563
564 // No voltage conversion
565 gpadc_reg_read(GPADC_REG_CH0_DATA + HAL_GPADC_CHAN_ADCKEY, &adc_val);
566 adc_val = GET_BITFIELD(adc_val, DATA_CHAN0);
567 } else {
568 adc_val = HAL_GPADC_BAD_VALUE;
569 }
570 adc_val = hal_gpadc_adc2volt(adc_val);
571 ((HAL_ADCKEY_EVENT_CB_T)gpadc_event_cb[HAL_GPADC_CHAN_ADCKEY])(adckey_irq, adc_val);
572 }
573 }
574 }
575
hal_gpadc_get_volt(enum HAL_GPADC_CHAN_T ch,HAL_GPADC_MV_T * volt)576 bool hal_gpadc_get_volt(enum HAL_GPADC_CHAN_T ch, HAL_GPADC_MV_T *volt)
577 {
578 bool res = false;
579 unsigned short read_val;
580
581 if (ch >= HAL_GPADC_CHAN_QTY) {
582 return res;
583 }
584
585 gpadc_reg_read(GPADC_REG_INT_RAW_STS, &read_val);
586
587 if (read_val & CHAN_DATA_VALID_INTR(1<<ch)) {
588 // Clear the channel valid status
589 gpadc_reg_write(GPADC_REG_INT_CLR, CHAN_DATA_INTR_CLR(1<<ch));
590
591 gpadc_reg_read(GPADC_REG_CH0_DATA + ch, &read_val);
592 read_val = GET_BITFIELD(read_val, DATA_CHAN0);
593 *volt = hal_gpadc_adc2volt(read_val);
594 res = true;
595 }
596
597 return res;
598 }
599
hal_gpadc_irq_control(void)600 static void hal_gpadc_irq_control(void)
601 {
602 if (gpadc_irq_enabled || adckey_irq_enabled) {
603 if (!irq_enabled) {
604 irq_enabled = true;
605 #ifdef PMU_IRQ_UNIFIED
606 pmu_set_irq_unified_handler(PMU_IRQ_TYPE_GPADC, hal_gpadc_irq_handler);
607 #else
608 NVIC_SetVector(GPADC_IRQn, (uint32_t)hal_gpadc_irq_handler);
609 NVIC_SetPriority(GPADC_IRQn, IRQ_PRIORITY_NORMAL);
610 NVIC_ClearPendingIRQ(GPADC_IRQn);
611 NVIC_EnableIRQ(GPADC_IRQn);
612 #endif
613 }
614 } else {
615 if (irq_enabled) {
616 irq_enabled = false;
617 #ifdef PMU_IRQ_UNIFIED
618 pmu_set_irq_unified_handler(PMU_IRQ_TYPE_GPADC, NULL);
619 #else
620 NVIC_DisableIRQ(GPADC_IRQn);
621 #endif
622 }
623 }
624 }
625
hal_gpadc_open(enum HAL_GPADC_CHAN_T channel,enum HAL_GPADC_ATP_T atp,HAL_GPADC_EVENT_CB_T cb)626 int hal_gpadc_open(enum HAL_GPADC_CHAN_T channel, enum HAL_GPADC_ATP_T atp, HAL_GPADC_EVENT_CB_T cb)
627 {
628 uint32_t lock;
629 unsigned short val;
630 unsigned short reg_start_mask;
631
632 #ifdef GPADC_DYNAMIC_DATA_BITS
633 if (gpadc_data_bits == 0) {
634 gpadc_data_bits = pmu_get_gpadc_data_bits();
635 ASSERT(10 <= gpadc_data_bits && gpadc_data_bits <= 16, "GPADC value bits not in range: %u", gpadc_data_bits);
636 }
637 #endif
638
639 if (channel >= HAL_GPADC_CHAN_QTY) {
640 return -1;
641 }
642
643 // NOTE: ADCKEY callback is not set here, but in hal_adckey_set_irq_handler()
644 if (channel != HAL_GPADC_CHAN_ADCKEY) {
645 gpadc_event_cb[channel] = cb;
646 gpadc_atp[channel] = atp;
647 }
648
649 switch (channel) {
650 case HAL_GPADC_CHAN_BATTERY:
651 // Enable vbat measurement clock
652 // vbat div enable
653 lock = int_lock();
654 gpadc_reg_read(GPADC_REG_VBAT_EN, &val);
655 val |= REG_PU_VBAT_DIV;
656 gpadc_reg_write(GPADC_REG_VBAT_EN, val);
657 int_unlock(lock);
658 #ifndef VBAT_DIV_ALWAYS_ON
659 // GPADC VBAT needs 10us to be stable and consumes 13mA current
660 hal_sys_timer_delay_us(20);
661 #endif
662 // FALLTHROUGH
663 case HAL_GPADC_CHAN_0:
664 case HAL_GPADC_CHAN_2:
665 case HAL_GPADC_CHAN_3:
666 case HAL_GPADC_CHAN_4:
667 case HAL_GPADC_CHAN_5:
668 case HAL_GPADC_CHAN_6:
669 case HAL_GPADC_CHAN_ADCKEY:
670 lock = int_lock();
671
672 #ifdef DCDC_CLOCK_CONTROL
673 if (channel != HAL_GPADC_CHAN_ADCKEY) {
674 hal_cmu_dcdc_clock_enable(HAL_CMU_DCDC_CLOCK_USER_GPADC);
675 }
676 #endif
677
678 #if defined(CHIP_BEST1305) || defined(CHIP_BEST1501) || defined(CHIP_BEST1600) || \
679 defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A)
680 if (channel == HAL_GPADC_CHAN_3){
681 pmu_led_set_hiz(HAL_GPIO_PIN_LED2);
682 }
683 #endif
684
685 // Int mask
686 if (channel == HAL_GPADC_CHAN_ADCKEY || gpadc_event_cb[channel]) {
687 // 1) Always enable ADCKEY mask
688 // 2) Enable mask if handler is not null
689 gpadc_reg_read(GPADC_REG_INT_MASK, &val);
690 val |= CHAN_DATA_INTR_MSK(1<<channel);
691 gpadc_reg_write(GPADC_REG_INT_MASK, val);
692 gpadc_irq_mask = val;
693 gpadc_irq_enabled = true;
694 hal_gpadc_irq_control();
695 }
696
697 // Int enable
698 gpadc_reg_read(GPADC_REG_INT_EN, &val);
699 val |= CHAN_DATA_INTR_EN(1<<channel);
700 gpadc_reg_write(GPADC_REG_INT_EN, val);
701
702 // Clear the channel valid status
703 gpadc_reg_write(GPADC_REG_INT_CLR, CHAN_DATA_INTR_CLR(1<<channel));
704
705 // Channel enable
706 if (channel == HAL_GPADC_CHAN_ADCKEY) {
707 reg_start_mask = KEY_START;
708 } else {
709 hal_gpadc_update_atp();
710 reg_start_mask = GPADC_START;
711 if (GPADC_REG_START == GPADC_REG_CH_EN) {
712 reg_start_mask |= CHAN_EN_REG(1<<channel);
713 gpadc_chan_en = reg_start_mask;
714 } else {
715 gpadc_reg_read(GPADC_REG_CH_EN, &val);
716 val |= CHAN_EN_REG(1<<channel);
717 gpadc_reg_write(GPADC_REG_CH_EN, val);
718 gpadc_chan_en = val;
719 }
720 }
721
722 // GPADC enable
723 gpadc_reg_read(GPADC_REG_START, &val);
724 val |= reg_start_mask;
725 gpadc_reg_write(GPADC_REG_START, val);
726
727 int_unlock(lock);
728 break;
729 default:
730 break;
731 }
732
733 return 0;
734 }
735
hal_gpadc_close(enum HAL_GPADC_CHAN_T channel)736 int hal_gpadc_close(enum HAL_GPADC_CHAN_T channel)
737 {
738 uint32_t lock;
739 unsigned short val;
740 unsigned short chan_int_en;
741 unsigned short reg_start;
742
743 if (channel >= HAL_GPADC_CHAN_QTY) {
744 return -1;
745 }
746
747 if (channel != HAL_GPADC_CHAN_ADCKEY) {
748 gpadc_atp[channel] = HAL_GPADC_ATP_NULL;
749 }
750
751 switch (channel) {
752 case HAL_GPADC_CHAN_BATTERY:
753 #ifndef VBAT_DIV_ALWAYS_ON
754 // disable vbat measurement clock
755 // vbat div disable
756 lock = int_lock();
757 gpadc_reg_read(GPADC_REG_VBAT_EN, &val);
758 val &= ~REG_PU_VBAT_DIV;
759 gpadc_reg_write(GPADC_REG_VBAT_EN, val);
760 int_unlock(lock);
761 #endif
762 case HAL_GPADC_CHAN_0:
763 case HAL_GPADC_CHAN_2:
764 case HAL_GPADC_CHAN_3:
765 case HAL_GPADC_CHAN_4:
766 case HAL_GPADC_CHAN_5:
767 case HAL_GPADC_CHAN_6:
768 case HAL_GPADC_CHAN_ADCKEY:
769 lock = int_lock();
770
771 // Int mask
772 gpadc_reg_read(GPADC_REG_INT_MASK, &val);
773 val &= ~CHAN_DATA_INTR_MSK(1<<channel);
774 gpadc_reg_write(GPADC_REG_INT_MASK, val);
775 gpadc_irq_mask = val;
776
777 // Int enable
778 gpadc_reg_read(GPADC_REG_INT_EN, &chan_int_en);
779 chan_int_en &= ~CHAN_DATA_INTR_EN(1<<channel);
780 gpadc_reg_write(GPADC_REG_INT_EN, chan_int_en);
781
782 // Channel/GPADC enable
783 gpadc_reg_read(GPADC_REG_START, ®_start);
784 if (channel == HAL_GPADC_CHAN_ADCKEY) {
785 reg_start &= ~KEY_START;
786 } else {
787 if (GPADC_REG_START == GPADC_REG_CH_EN) {
788 reg_start &= ~CHAN_EN_REG(1<<channel);
789 gpadc_chan_en = reg_start;
790 } else {
791 gpadc_reg_read(GPADC_REG_CH_EN, &val);
792 val &= ~CHAN_EN_REG(1<<channel);
793 gpadc_reg_write(GPADC_REG_CH_EN, val);
794 gpadc_chan_en = val;
795 }
796 if (gpadc_chan_en & CHAN_EN_REG((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6))) {
797 hal_gpadc_update_atp();
798 } else {
799 reg_start &= ~GPADC_START;
800 }
801 }
802 gpadc_reg_write(GPADC_REG_START, reg_start);
803
804 #ifdef DCDC_CLOCK_CONTROL
805 if ((reg_start & GPADC_START) == 0) {
806 hal_cmu_dcdc_clock_disable(HAL_CMU_DCDC_CLOCK_USER_GPADC);
807 }
808 #endif
809
810 if ((gpadc_irq_mask & CHAN_DATA_INTR_MSK((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7))) == 0) {
811 gpadc_irq_enabled = false;
812 hal_gpadc_irq_control();
813 }
814
815 int_unlock(lock);
816 break;
817 default:
818 break;
819 }
820
821 return 0;
822 }
823
hal_gpadc_sleep(void)824 void hal_gpadc_sleep(void)
825 {
826 unsigned short val;
827
828 #if defined(CHIP_BEST1305) || defined(CHIP_BEST1501) || defined(CHIP_BEST1600) || \
829 defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A)
830 return;
831 #endif
832
833 gpadc_reg_read(GPADC_REG_START, &val);
834 if (val & GPADC_START) {
835 val &= ~GPADC_START;
836 gpadc_reg_write(GPADC_REG_START, val);
837 }
838 }
839
hal_gpadc_wakeup(void)840 void hal_gpadc_wakeup(void)
841 {
842 unsigned short val;
843
844 #if defined(CHIP_BEST1305) || defined(CHIP_BEST1501) || defined(CHIP_BEST1600) || \
845 defined(CHIP_BEST2300) || defined(CHIP_BEST2300P) || defined(CHIP_BEST2300A)
846 return;
847 #endif
848
849 if (gpadc_chan_en & CHAN_EN_REG((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6))) {
850 gpadc_reg_read(GPADC_REG_START, &val);
851 val |= GPADC_START;
852 gpadc_reg_write(GPADC_REG_START, val);
853 }
854 }
855
hal_adckey_set_irq_handler(HAL_ADCKEY_EVENT_CB_T cb)856 void hal_adckey_set_irq_handler(HAL_ADCKEY_EVENT_CB_T cb)
857 {
858 gpadc_event_cb[HAL_GPADC_CHAN_ADCKEY] = (HAL_GPADC_EVENT_CB_T)cb;
859 }
860
hal_adckey_set_irq(enum HAL_ADCKEY_IRQ_T type)861 int hal_adckey_set_irq(enum HAL_ADCKEY_IRQ_T type)
862 {
863 uint32_t lock;
864 uint16_t val;
865 uint16_t set_mask;
866 uint16_t clr_mask;
867 uint16_t set_en;
868 uint16_t clr_en;
869
870 set_mask = 0;
871 clr_mask = 0;
872 set_en = 0;
873 clr_en = 0;
874 if (type == HAL_ADCKEY_IRQ_NONE) {
875 clr_mask = KEY_RELEASE_INTR_MSK | KEY_PRESS_INTR_MSK | KEY_ERR0_INTR_MSK | KEY_ERR1_INTR_MSK;
876 clr_en = KEY_RELEASE_INTR_EN | KEY_PRESS_INTR_EN | KEY_ERR0_INTR_EN | KEY_ERR1_INTR_EN;
877 adckey_irq_enabled = false;
878 } else if (type == HAL_ADCKEY_IRQ_PRESSED) {
879 set_mask = KEY_PRESS_INTR_MSK | KEY_ERR0_INTR_MSK | KEY_ERR1_INTR_MSK;
880 clr_mask = KEY_RELEASE_INTR_MSK;
881 set_en = KEY_PRESS_INTR_EN | KEY_ERR0_INTR_EN | KEY_ERR1_INTR_EN;
882 clr_en = KEY_RELEASE_INTR_EN;
883 adckey_irq_enabled = true;
884 } else if (type == HAL_ADCKEY_IRQ_RELEASED) {
885 set_mask = KEY_RELEASE_INTR_MSK | KEY_ERR0_INTR_MSK | KEY_ERR1_INTR_MSK;
886 clr_mask = KEY_PRESS_INTR_MSK;
887 set_en = KEY_RELEASE_INTR_EN | KEY_ERR0_INTR_EN | KEY_ERR1_INTR_EN;
888 clr_en = KEY_PRESS_INTR_EN;
889 adckey_irq_enabled = true;
890 } else if (type == HAL_ADCKEY_IRQ_BOTH) {
891 set_mask = KEY_RELEASE_INTR_MSK | KEY_PRESS_INTR_MSK | KEY_ERR0_INTR_MSK | KEY_ERR1_INTR_MSK;
892 set_en = KEY_RELEASE_INTR_EN | KEY_PRESS_INTR_EN | KEY_ERR0_INTR_EN | KEY_ERR1_INTR_EN;
893 adckey_irq_enabled = true;
894 } else {
895 return 1;
896 }
897
898 #ifdef DCDC_CLOCK_CONTROL
899 if (adckey_irq_enabled) {
900 hal_cmu_dcdc_clock_enable(HAL_CMU_DCDC_CLOCK_USER_ADCKEY);
901 }
902 // Never disable adckey clock
903 #endif
904
905 lock = int_lock();
906
907 gpadc_reg_read(GPADC_REG_INT_MASK, &val);
908 val &= ~clr_mask;
909 val |= set_mask;
910 gpadc_reg_write(GPADC_REG_INT_MASK, val);
911 gpadc_irq_mask = val;
912
913 gpadc_reg_read(GPADC_REG_INT_EN, &val);
914 val &= ~clr_en;
915 val |= set_en;
916 gpadc_reg_write(GPADC_REG_INT_EN, val);
917
918 hal_gpadc_irq_control();
919
920 int_unlock(lock);
921
922 return 0;
923 }
924
925 #endif // !GPADC_CHIP_SPECIFIC
926
927