• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
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  * Description: Provides V154 HAL adc \n
16  *
17  * History: \n
18  * 2024-02-01, Create file. \n
19  */
20 #include "common_def.h"
21 #include "tcxo.h"
22 #include "hal_adc.h"
23 #include "debug_print.h"
24 #include "osal_debug.h"
25 #include "pinctrl_porting.h"
26 #include "pinctrl.h"
27 #include "gpio.h"
28 #include "adc_porting.h"
29 #include "hal_adc_v154.h"
30 
31 #define DELAY_500US 500
32 #define DELAY_300US 300
33 #define FIFO_DATA_LENS 128
34 #define MANUAL_CALI_LOW_LIMIT1 0
35 #define MANUAL_CALI_UPPER_LIMIT1 2
36 #define MANUAL_CALI_LOW_LIMIT2 3
37 #define MANUAL_CALI_UPPER_LIMIT2 31
38 #define MANUAL_CALI_LOW_LIMIT3 32
39 #define MANUAL_CALI_UPPER_LIMIT3 60
40 #define MANUAL_CALI_LOW_LIMIT4 61
41 #define MANUAL_CALI_UPPER_LIMIT4 63
42 #define MANUAL_CALI_GAIN 3
43 #define MANUAL_CALI_THRESHOLD 63
44 #define COUNT_THRESHOLD  1000
45 #define VOLTAGE_UPPER_LIMIT 3600
46 #define CH_NUM 6
47 
48 static hal_adc_callback_t g_adc_receive_data_callback = NULL;
49 
50 uint32_t g_fifo_data[FIFO_DATA_LENS];
51 uint32_t g_ch_output_data[CH_NUM][FIFO_DATA_LENS];
52 uint32_t g_ch_data_cnt[CH_NUM];
53 
54 static bool g_adc_auto_scan_status = false;
55 
hal_adc_v154_init(void)56 static errcode_t hal_adc_v154_init(void)
57 {
58     if (hal_adc_v154_regs_init() != ERRCODE_SUCC) {
59         return ERRCODE_ADC_REG_ADDR_INVALID;
60     }
61     return ERRCODE_SUCC;
62 }
63 
hal_adc_v154_deinit(void)64 static errcode_t hal_adc_v154_deinit(void)
65 {
66     return ERRCODE_SUCC;
67 }
68 
hal_adc_simulation_cfg(void)69 static void hal_adc_simulation_cfg(void)
70 {
71     hal_adc_simu_cfg1();
72     hal_adc_simu_cfg2();
73     hal_adc_simu_cfg3();
74     hal_adc_simu_ldo_start();
75     uapi_tcxo_delay_us(DELAY_500US);
76     hal_adc_simu_cfg4();
77     uapi_tcxo_delay_us(DELAY_300US);
78     hal_adc_simu_cfg5();
79     hal_adc_simu_cfg6();
80     uapi_tcxo_delay_us(DELAY_300US);
81     hal_adc_simu_rst_clr();
82 }
83 
hal_adc_offset_auto_cali(void)84 static void hal_adc_offset_auto_cali(void)
85 {
86     hal_adc_offset_cali_state_clr();
87     hal_adc_offset_cali_data_spi_refresh();
88     hal_adc_offset_cali_set();
89     hal_adc_offset_cali_enable(1);
90     uint32_t cnt = 0;
91     while (hal_adc_offset_cali_sts() != 1) {
92         if (cnt > COUNT_THRESHOLD) {
93             break;
94         }
95         cnt++;
96     }
97     hal_adc_offset_cali_enable(0);
98 }
99 
hal_adc_offset_manual_cali(void)100 static void hal_adc_offset_manual_cali(void)
101 {
102     uint32_t auto_cali_data;
103     uint32_t temp;
104     auto_cali_data = hal_adc_auto_offset_cali_data_get();
105     if (auto_cali_data >= MANUAL_CALI_LOW_LIMIT1 && auto_cali_data <= MANUAL_CALI_UPPER_LIMIT1) {
106         temp = 0;
107     } else if (auto_cali_data >= MANUAL_CALI_LOW_LIMIT2 && auto_cali_data <= MANUAL_CALI_UPPER_LIMIT2) {
108         temp = auto_cali_data - MANUAL_CALI_GAIN;
109     } else if (auto_cali_data >= MANUAL_CALI_LOW_LIMIT3 && auto_cali_data <= MANUAL_CALI_UPPER_LIMIT3) {
110         temp = auto_cali_data + MANUAL_CALI_GAIN;
111     } else if (auto_cali_data >= MANUAL_CALI_LOW_LIMIT4 && auto_cali_data <= MANUAL_CALI_UPPER_LIMIT4) {
112         temp = MANUAL_CALI_THRESHOLD;
113     }
114     hal_adc_manual_offset_cali_set(temp);
115     hal_adc_offset_cali_enable(1);
116     hal_adc_cfg_offset_cali_data_enable();
117     hal_adc_offset_cali_data_spi_refresh();
118     uint32_t cnt = 0;
119     while (hal_adc_offset_cali_sts() != 1) {
120         if (cnt > COUNT_THRESHOLD) {
121             break;
122         }
123         cnt++;
124     }
125     hal_adc_offset_cali_enable(0);
126 }
127 
hal_adc_cap_auto_cali(void)128 static void hal_adc_cap_auto_cali(void)
129 {
130     hal_adc_cfg_cap_cali_finish_clr();
131     hal_adc_cfg_intr_gain_state_clr();
132     hal_adc_date_spi_refresh_clr();
133     hal_adc_cfg_cap_cali_set();
134     hal_adc_cfg_cap_cali_enable(1);
135     uint32_t cnt = 0;
136     while (hal_adc_rpt_cap_cali_sts() != 1) {
137         if (cnt > COUNT_THRESHOLD) {
138             break;
139         }
140         cnt++;
141     }
142     hal_adc_cfg_cap_cali_enable(0);
143 }
144 
hal_adc_offset_manual_cali_inc(void)145 static void hal_adc_offset_manual_cali_inc(void)
146 {
147     uint32_t temp;
148     temp = 0;
149     hal_adc_manual_offset_cali_set(temp);
150     hal_adc_offset_cali_enable(1);
151     hal_adc_cfg_offset_cali_data_enable();
152     hal_adc_offset_cali_data_spi_refresh();
153     uint32_t cnt = 0;
154     while (hal_adc_offset_cali_sts() != 1) {
155         if (cnt > COUNT_THRESHOLD) {
156             break;
157         }
158         cnt++;
159     }
160     hal_adc_offset_cali_enable(0);
161 }
162 
adc_port_calibration(void)163 void adc_port_calibration(void)
164 {
165     hal_adc_offset_auto_cali();
166     hal_adc_offset_manual_cali();
167     hal_adc_cap_auto_cali();
168     hal_adc_offset_manual_cali_inc();
169 }
170 
adc_process_before_use_adc(void)171 static void adc_process_before_use_adc(void)
172 {
173     hal_adc_cfg_gain_cali_enable();
174     uint32_t cnt = 0;
175     while (hal_adc_gain_unit_get() != 0) {
176         if (cnt > COUNT_THRESHOLD) {
177             break;
178         }
179         cnt++;
180     }
181     cnt = 0;
182     while (hal_adc_reg_fifo_isnt_empty_get() == 1) {
183         (void)hal_adc_reg_fifo_data_get();
184         if (cnt > COUNT_THRESHOLD) {
185             break;
186         }
187         cnt++;
188     }
189 }
190 
hal_adc_v154_power_en(afe_scan_mode_t afe_scan_mode,bool on)191 static void hal_adc_v154_power_en(afe_scan_mode_t afe_scan_mode, bool on)
192 {
193     unused(afe_scan_mode);
194     if (on) {
195         hal_adc_soft_rst(0);
196         hal_adc_soft_rst(1);
197         hal_adc_simulation_cfg();
198         adc_port_calibration();
199         adc_process_before_use_adc();
200         hal_adc_fifo_waterline_set();
201         hal_adc_reg_irg_fifo_interrupt_mask();
202     }
203 }
204 
hal_adc_channel_trans_to_gpio_get(adc_channel_t ch)205 static pin_t hal_adc_channel_trans_to_gpio_get(adc_channel_t ch)
206 {
207     switch (ch) {
208         case ADC_CHANNEL_0:
209             return GPIO_07;
210         case ADC_CHANNEL_1:
211             return GPIO_08;
212         case ADC_CHANNEL_2:
213             return GPIO_09;
214         case ADC_CHANNEL_3:
215             return GPIO_10;
216         case ADC_CHANNEL_4:
217             return GPIO_11;
218         case ADC_CHANNEL_5:
219             return GPIO_12;
220         default:
221             return PIN_NONE;
222     }
223 }
224 
hal_adc_v154_channel_set(adc_channel_t ch,bool on)225 errcode_t hal_adc_v154_channel_set(adc_channel_t ch, bool on)
226 {
227     if (ch >= ADC_CHANNEL_MAX_NUM) {
228         return ERRCODE_ADC_INVALID_CH_TYPE;
229     }
230     pin_t pin_number;
231     pin_number = hal_adc_channel_trans_to_gpio_get(ch);
232     if (on) {
233         errcode_t ret;
234         ret = uapi_pin_set_pull(pin_number, PIN_PULL_TYPE_DISABLE);
235         if (ret != ERRCODE_SUCC) {
236             return ERRCODE_FAIL;
237         }
238         ret = uapi_pin_set_mode(pin_number, PIN_MODE_0);
239         if (ret != ERRCODE_SUCC) {
240             return ERRCODE_FAIL;
241         }
242         ret = uapi_gpio_set_dir(pin_number, GPIO_DIRECTION_INPUT);
243         if (ret != ERRCODE_SUCC) {
244             return ERRCODE_FAIL;
245         }
246     }
247 
248     return ERRCODE_SUCC;
249 }
250 
hal_adc_fifo_data_print(void)251 static void hal_adc_fifo_data_print(void)
252 {
253     adc_fifo_data_str_t ret;
254     uint32_t code, ch, index, voltage;
255     uint32_t param2 = 0x1 << 14;
256     uint32_t param3 = 0x1 << 15;
257 
258     uint32_t data_s = 1, data_b = 1, data_k = 1;
259 
260     bool next = false;
261 
262     errcode_t res = adc_port_get_cali_param((uint8_t *)&data_s, (uint8_t *)&data_b, (uint8_t *)&data_k);
263     if (res != ERRCODE_SUCC) {
264         print_str("efuse read failed!\r\n");
265     }
266 
267     memset_s(g_ch_data_cnt, sizeof(uint32_t) * CH_NUM, 0, sizeof(uint32_t) * CH_NUM);
268 
269     for (uint32_t i = 0; i < FIFO_DATA_LENS; i++) {
270         ret.d32 = g_fifo_data[i];
271         code = ret.b.data;
272         ch = ret.b.channel;
273         g_ch_data_cnt[ch]++;
274         index = g_ch_data_cnt[ch];
275         if (ret.b.data == 0) {
276             break;
277         }
278 
279         if (data_k == 0) {
280             voltage = code * VOLTAGE_UPPER_LIMIT / param2;
281         } else {
282             if (data_s == 0) {
283                 voltage = code * VOLTAGE_UPPER_LIMIT / data_k - data_b * VOLTAGE_UPPER_LIMIT / param3;
284             } else {
285                 voltage = code * VOLTAGE_UPPER_LIMIT / data_k + data_b * VOLTAGE_UPPER_LIMIT / param3;
286             }
287         }
288         g_ch_output_data[ch][index] = voltage;
289     }
290     for (uint32_t idx = 0; idx < CH_NUM; idx++) {
291         if (g_ch_data_cnt[idx] > 0 && g_adc_receive_data_callback != NULL) {
292             g_adc_receive_data_callback(idx, g_ch_output_data[idx], g_ch_data_cnt[idx], &next);
293         }
294     }
295 }
296 
hal_adc_v154_auto_scan_enable(bool en)297 static void hal_adc_v154_auto_scan_enable(bool en)
298 {
299     if (en) {
300         hal_adc_start_sample();
301         g_adc_auto_scan_status = true;
302     } else {
303         hal_adc_stop_sample();
304         g_adc_auto_scan_status = false;
305     }
306 }
307 
hal_adc_v154_auto_scan_ch_enable(adc_channel_t ch,bool en)308 static errcode_t hal_adc_v154_auto_scan_ch_enable(adc_channel_t ch, bool en)
309 {
310     hal_adc_auto_scan_mode_set(ch, en);
311     if (!en) {
312         hal_adc_fifo_data_print();
313         hal_adc_v154_auto_scan_enable(false);
314     }
315     return ERRCODE_SUCC;
316 }
317 
hal_adc_v154_auto_scan_ch_config(adc_channel_t ch,hal_adc_scan_config_t * config,hal_adc_callback_t callback)318 static errcode_t hal_adc_v154_auto_scan_ch_config(adc_channel_t ch, hal_adc_scan_config_t *config,
319                                                   hal_adc_callback_t callback)
320 {
321     unused(config);
322     g_adc_receive_data_callback = callback;
323     hal_adc_v154_channel_set(ch, true);
324     hal_adc_v154_auto_scan_ch_enable(ch, true);
325     hal_adc_v154_auto_scan_enable(true);
326 
327     return ERRCODE_SUCC;
328 }
329 
hal_adc_v154_auto_scan_is_enabled(void)330 static bool hal_adc_v154_auto_scan_is_enabled(void)
331 {
332     return g_adc_auto_scan_status;
333 }
334 
hal_adc_irq_handler(void)335 void hal_adc_irq_handler(void)
336 {
337     uint32_t index = 0;
338     uint32_t cnt = 0;
339     while (hal_adc_reg_fifo_isnt_empty_get()) {
340         if (index < FIFO_DATA_LENS) {
341             g_fifo_data[index++] = hal_adc_reg_fifo_data_get();
342         } else {
343             hal_adc_reg_fifo_data_get();
344             if (cnt > COUNT_THRESHOLD) {
345                 break;
346             }
347             cnt++;
348         }
349     }
350 }
351 
hal_adc_v154_manual_sample(adc_channel_t channel)352 static int32_t hal_adc_v154_manual_sample(adc_channel_t channel)
353 {
354     unused(channel);
355     return 0;
356 }
357 
358 static hal_adc_funcs_t g_hal_adc_v154_funcs = {
359     .init = hal_adc_v154_init,
360     .deinit = hal_adc_v154_deinit,
361     .power_en = hal_adc_v154_power_en,
362     .ch_set = hal_adc_v154_channel_set,
363 #if defined(CONFIG_ADC_SUPPORT_AUTO_SCAN)
364     .ch_config = hal_adc_v154_auto_scan_ch_config,
365     .ch_enable = hal_adc_v154_auto_scan_ch_enable,
366     .enable = hal_adc_v154_auto_scan_enable,
367     .isenable = hal_adc_v154_auto_scan_is_enabled,
368 #endif /* CONFIG_ADC_SUPPORT_AUTO_SCAN */
369     .manual = hal_adc_v154_manual_sample
370 };
371 
hal_adc_v154_funcs_get(void)372 hal_adc_funcs_t *hal_adc_v154_funcs_get(void)
373 {
374     return &g_hal_adc_v154_funcs;
375 }
376