1 /******************************************************************************
2 * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3 * All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************/
18
19 /********************************************************************************************************
20 * @file adc.h
21 *
22 * @brief This is the header file for B91
23 *
24 * @author Driver Group
25 *
26 *******************************************************************************************************/
27 /** @page ADC
28 *
29 * Introduction
30 * ===============
31 * TLSRB91 supports hardware ADC function.
32 *
33 * API Reference
34 * ===============
35 * Header File: adc.h
36 */
37 #pragma once
38
39
40 #include "dma.h"
41 #include "compiler.h"
42 #include "gpio.h"
43 #include "reg_include/register_b91.h"
44
45 typedef enum{
46 ADC_VREF_0P9V = 0x01,
47 ADC_VREF_1P2V = 0x02,
48 }adc_ref_vol_e;
49 typedef enum{
50 ADC_VBAT_DIV_OFF = 0,
51 ADC_VBAT_DIV_1F3 = 0x02,
52 }adc_vbat_div_e;
53
54 typedef enum {
55 NOINPUTN = 0,
56 ADC_GPIO_PB0N = 0x01,
57 ADC_GPIO_PB1N = 0x02,
58 ADC_GPIO_PB2N = 0x03,
59 ADC_GPIO_PB3N = 0x04,
60 ADC_GPIO_PB4N = 0x05,
61 ADC_GPIO_PB5N = 0x06,
62 ADC_GPIO_PB6N = 0x07,
63 ADC_GPIO_PB7N = 0x08,
64 ADC_GPIO_PD0N = 0x09,
65 ADC_GPIO_PD1N = 0x0a,
66 ADC_TEMSENSORN_EE = 0x0e,
67 GND = 0x0f,
68 }adc_input_nch_e;
69 typedef enum {
70 NOINPUTP = 0,
71 ADC_GPIO_PB0P = 0x01,
72 ADC_GPIO_PB1P = 0x02,
73 ADC_GPIO_PB2P = 0x03,
74 ADC_GPIO_PB3P = 0x04,
75 ADC_GPIO_PB4P = 0x05,
76 ADC_GPIO_PB5P = 0x06,
77 ADC_GPIO_PB6P = 0x07,
78 ADC_GPIO_PB7P = 0x08,
79 ADC_GPIO_PD0P = 0x09,
80 ADC_GPIO_PD1P = 0x0a,
81 ADC_TEMSENSORP_EE = 0x0e,
82 ADC_VBAT = 0x0f,
83 }adc_input_pch_e;
84 /**
85 * @brief adc input pin type
86 * | | |
87 * | :-------- | :----------- |
88 * | <15:12> | <11:0> |
89 * |adc channel| gpio pin |
90 */
91 typedef enum{
92 ADC_GPIO_PB0 = GPIO_PB0 | (0x1<<12),
93 ADC_GPIO_PB1 = GPIO_PB1 | (0x2<<12),
94 ADC_GPIO_PB2 = GPIO_PB2 | (0x3<<12),
95 ADC_GPIO_PB3 = GPIO_PB3 | (0x4<<12),
96 ADC_GPIO_PB4 = GPIO_PB4 | (0x5<<12),
97 ADC_GPIO_PB5 = GPIO_PB5 | (0x6<<12),
98 ADC_GPIO_PB6 = GPIO_PB6 | (0x7<<12),
99 ADC_GPIO_PB7 = GPIO_PB7 | (0x8<<12),
100 ADC_GPIO_PD0 = GPIO_PD0 | (0x9<<12),
101 ADC_GPIO_PD1 = GPIO_PD1 | (0xa<<12),
102 }adc_input_pin_def_e;
103 typedef enum{
104 ADC_GPIO_MODE,
105 ADC_VBAT_MODE,
106 }adc_input_pin_mode_e;
107
108 typedef enum{
109 ADC_RES8 = 0,
110 ADC_RES10 = 0x01,
111 ADC_RES12 = 0x02,
112 ADC_RES14 = 0x03,
113 }adc_res_e;
114
115 typedef enum{
116 ADC_SAMPLE_CYC_3,
117 ADC_SAMPLE_CYC_6,
118 ADC_SAMPLE_CYC_9,
119 ADC_SAMPLE_CYC_12,
120 ADC_SAMPLE_CYC_15,
121 ADC_SAMPLE_CYC_18,
122 ADC_SAMPLE_CYC_21,
123 ADC_SAMPLE_CYC_24,
124 ADC_SAMPLE_CYC_27,
125 ADC_SAMPLE_CYC_30,
126 ADC_SAMPLE_CYC_33,
127 ADC_SAMPLE_CYC_36,
128 ADC_SAMPLE_CYC_39,
129 ADC_SAMPLE_CYC_42,
130 ADC_SAMPLE_CYC_45,
131 ADC_SAMPLE_CYC_48,
132 }adc_sample_cycle_e;
133
134 typedef enum{
135 ADC_SAMPLE_FREQ_23K,
136 ADC_SAMPLE_FREQ_48K,
137 ADC_SAMPLE_FREQ_96K,
138 }adc_sample_freq_e;
139
140 typedef enum{
141 ADC_MISC_CHN = BIT(2),
142 }adc_chn_e;
143
144 typedef enum{
145 ADC_PRESCALE_1 = 0x00,//Only for internal testing and temperature sensor sampling
146 // ADC_PRESCALE_1F2 = 0x01,//Only for internal testing
147 ADC_PRESCALE_1F4 = 0x02,
148 // ADC_PRESCALE_1F8 = 0x03,//Only for internal testing
149 }adc_pre_scale_e;
150 enum{
151 ADC_MAX_STATE_NUM = 0x02,
152 };
153
154 /**
155 * @brief This function open sar_adc power.
156 * @return none.
157 */
adc_power_on(void)158 static inline void adc_power_on(void)
159 {
160 analog_write_reg8 (areg_adc_pga_ctrl, (analog_read_reg8(areg_adc_pga_ctrl)&(~FLD_SAR_ADC_POWER_DOWN)));
161 }
162 /**
163 * @brief This function close sar_adc power.
164 * @return none
165 */
adc_power_off(void)166 static inline void adc_power_off(void)
167 {
168 analog_write_reg8 (areg_adc_pga_ctrl, (analog_read_reg8(areg_adc_pga_ctrl)|FLD_SAR_ADC_POWER_DOWN));
169 }
170 /**
171 * @brief This function reset adc module
172 * @return none
173 */
adc_reset(void)174 static inline void adc_reset(void)
175 {
176 reg_rst3 &= (~FLD_RST3_SARADC );
177 reg_rst3 |=FLD_RST3_SARADC;
178 }
179 /**
180 * @brief This function serves to enable adc sample fifo.
181 * @return none
182 */
adc_fifo_enable(void)183 static inline void adc_fifo_enable(void)
184 {
185 reg_i2s_cfg2 &= (~FLD_AUDIO_FIFO1_RST);
186 }
187 /**
188 * @brief This function serves to disable adc sample fifo.
189 * @return none
190 */
adc_fifo_disable(void)191 static inline void adc_fifo_disable(void)
192 {
193 reg_i2s_cfg2 |= FLD_AUDIO_FIFO1_RST;
194 }
195 /**
196 * @brief This function enable adc source clock: Pad_24M
197 * @return none
198 */
adc_clk_en(void)199 static inline void adc_clk_en(void)
200 {
201 analog_write_reg8(areg_adc_clk_setting , analog_read_reg8(areg_adc_clk_setting ) | FLD_CLK_24M_TO_SAR_EN);
202 }
203 /**
204 * @brief This function disable adc source clock: Pad_24M
205 * @return none
206 */
adc_clk_dis(void)207 static inline void adc_clk_dis(void)
208 {
209 analog_write_reg8(areg_adc_clk_setting , analog_read_reg8(areg_adc_clk_setting ) & (~FLD_CLK_24M_TO_SAR_EN));
210 }
211 /**
212 * @brief This function sets adc sample clk. adc sample clk = 24M/(1+div) div: 0~7.
213 * @param[in] div - the divider of adc sample clock.
214 * @return none
215 */
adc_set_clk(unsigned char div)216 static inline void adc_set_clk(unsigned char div)
217 {
218 analog_write_reg8(areg_adc_sample_clk_div, div);
219 }
220 /**
221 * @brief This function sets ADC input channel as misc channel.
222 * @return none
223 */
adc_set_m_chn_en(void)224 static inline void adc_set_m_chn_en(void)
225 {
226 analog_write_reg8(areg_adc_chn_en, FLD_ADC_CHN_EN_M | (ADC_MAX_STATE_NUM<<4) );
227 }
228 /**
229 * @brief This function serves to set resolution.
230 * @param[in] res - enum variable of ADC resolution.
231 * @return none
232 */
adc_set_resolution(adc_res_e res)233 static inline void adc_set_resolution(adc_res_e res)
234 {
235 analog_write_reg8(areg_adc_res_m, (analog_read_reg8(areg_adc_res_m)&(~FLD_ADC_RES_M)) | res);
236 }
237
238 /**
239 * @brief This function serves to set ADC sample time(the number of adc clocks for sample cycles) for the misc channel.
240 * @param[in] sample_cycle - enum variable of adc sample cycles.
241 * @return none
242 */
adc_set_tsample_cycle(adc_sample_cycle_e sample_cycle)243 static inline void adc_set_tsample_cycle(adc_sample_cycle_e sample_cycle)
244 {
245 //ana_ee<7:4> is reserved, so no need care its value
246 analog_write_reg8(areg_adc_tsmaple_m, sample_cycle); //optimize, <7:4> not cared
247 }
248 /**
249 * @brief This function open temperature sensor power.
250 * @return none
251 */
adc_temp_sensor_power_on(void)252 static inline void adc_temp_sensor_power_on(void)
253 {
254 analog_write_reg8(areg_temp_sensor_ctrl, (analog_read_reg8(areg_temp_sensor_ctrl)&(~FLD_TEMP_SENSOR_POWER_DOWN)));
255 }
256 /**
257 * @brief This function close temperature sensor power.
258 * @return none
259 */
adc_temp_sensor_power_off(void)260 static inline void adc_temp_sensor_power_off(void)
261 {
262 analog_write_reg8(areg_temp_sensor_ctrl, (analog_read_reg8(areg_temp_sensor_ctrl)|FLD_TEMP_SENSOR_POWER_DOWN));
263 }
264 /**
265 * @brief This function serves to set input channel in differential_mode.
266 * @param[in] p_ain - enum variable of ADC analog positive input channel.
267 * @param[in] n_ain - enum variable of ADC analog negative input channel.
268 * @return none
269 */
adc_set_diff_input(adc_input_pch_e p_ain,adc_input_nch_e n_ain)270 static inline void adc_set_diff_input(adc_input_pch_e p_ain, adc_input_nch_e n_ain)
271 {
272 analog_write_reg8(areg_adc_res_m, analog_read_reg8(areg_adc_res_m) | FLD_ADC_EN_DIFF_CHN_M);
273 analog_write_reg8(areg_adc_ain_chn_misc, n_ain | p_ain<<4 );
274 }
275 /**
276 * @brief This function serves to set state and capture_state length.
277 * @param[in] r_max_mc - Value of length of "capture" state for MISC channel.
278 * @param[in] r_max_s - Value of length of "set" state for MISC channel.
279 * @return none
280 */
adc_set_state_length(unsigned short r_max_mc,unsigned char r_max_s)281 static inline void adc_set_state_length(unsigned short r_max_mc,unsigned char r_max_s)
282 {
283 analog_write_reg8(areg_r_max_mc, r_max_mc);
284 analog_write_reg8(areg_r_max_s, ((r_max_mc>>8)<<6)| (r_max_s & FLD_R_MAX_S));
285 }
286 /**
287 * @brief This function serves to config adc_dma_chn channel.
288 * @param[in] chn - the DMA channel
289 * @return none
290 */
291 void adc_set_dma_config(dma_chn_e chn);
292 /**
293 * @brief This function serves to start sample with adc DMA channel.
294 * @param[in] adc_data_buf - the address of data buffer
295 * @param[in] data_byte_len - the length of data size by byte
296 * @return none
297 */
298 void adc_start_sample_dma(unsigned short *adc_data_buf,unsigned int data_byte_len);
299 /**
300 * @brief This function is used to set IO port for ADC supply or ADC IO port voltage sampling.
301 * @param[in] mode - ADC gpio pin sample mode
302 * @param[in] pin - adc_input_pin_def_e ADC input gpio pin
303 * @return none
304 */
305 void adc_pin_config(adc_input_pin_mode_e mode ,adc_input_pin_def_e pin);
306 /**
307 * @brief This function is used to set two IO port configuration and set it as input channel of ADC difference IO port voltage sampling.
308 * @param[in] p_pin - enum variable of ADC analog positive input IO.
309 * @param[in] n_pin - enum variable of ADC analog negative input IO.
310 * @return none
311 */
312 void adc_set_diff_pin(adc_input_pin_def_e p_pin, adc_input_pin_def_e n_pin);
313 /**
314 * @brief This function serves to set the channel reference voltage.
315 * @param[in] v_ref - enum variable of ADC reference voltage.
316 * @return none
317 */
318 void adc_set_ref_voltage(adc_ref_vol_e v_ref);
319 /**
320 * @brief This function serves to set the sample frequency.
321 * @param[in] sample_freq - enum variable of ADC sample frequency.
322 * @return none
323 */
324 void adc_set_sample_rate(adc_sample_freq_e sample_freq);
325 /**
326 * @brief This function serves to set pre_scaling factor.
327 * @param[in] pre_scale - enum variable of ADC pre_scaling factor.
328 * @return none
329 */
330 void adc_set_scale_factor(adc_pre_scale_e pre_scale);
331 /**
332 * @brief This function servers to initialized ADC temperature sensor.When the reference voltage is set to 1.2V, and
333 * at the same time, the division factor is set to 1 the most accurate.
334 * @return none.
335 * @attention Temperature sensor suggested initial setting are Vref = 1.2V, pre_scale = 1.
336 * The user don't need to change it.
337 */
338 void adc_temperature_sample_init(void);
339 /**
340 * @brief This function serves to ADC gpio sample init.
341 * @param[in] pin - adc_input_pin_def_e ADC input gpio pin
342 * @param[in] v_ref - enum variable of ADC reference voltage.
343 * @param[in] pre_scale - enum variable of ADC pre_scaling factor.
344 * @param[in] sample_freq - enum variable of ADC sample frequency.
345 * @return none
346 * @attention gpio voltage sample suggested initial setting are Vref = 1.2V, pre_scale = 1/4.
347 * changed by chaofan.20201230.
348 */
349 void adc_gpio_sample_init(adc_input_pin_def_e pin,adc_ref_vol_e v_ref,adc_pre_scale_e pre_scale,adc_sample_freq_e sample_freq);
350
351 /**
352 * @brief This function servers to set ADC configuration with internal Vbat channel for ADC supply voltage sampling.
353 * @return none
354 * @attention Vbat channel battery voltage sample suggested initial setting are Vref = 1.2V, pre_scale = 1/4, vbat_div = off.
355 * The Vbat channel battery voltage sample range is 1.8~3.5V and is low accuracy,
356 * and must set sys_init with the mode for battery voltage less than 3.6V.
357 * For accurate battery voltage sampling or battery voltage > 3.6V, should use gpio sampling with some external voltage divider.
358 * Recommended configuration parameters:
359 * --3/4 external resistor voltage divider(total resistance 400k, without any capacitance),
360 * --1.2V Vref,
361 * --1/4 Scale
362 * --Sampling frequence below 48K.
363 * changed by chaofan.20201230.
364 */
365 void adc_battery_voltage_sample_init(void);
366 /**
367 * @brief This function serves to select Vbat voltage division factor
368 * @param[in] vbat_div - enum variable of Vbat division factor.
369 * @return none
370 */
371 void adc_set_vbat_divider(adc_vbat_div_e vbat_div);
372 /**
373 * @brief This function serves to ADC init.
374 * @param[in] v_ref - enum variable of ADC reference voltage.
375 * @param[in] pre_scale - enum variable of ADC pre_scaling factor.
376 * @param[in] sample_freq - enum variable of ADC sample frequency.
377 * @return none
378 * @attention Many features are configured in adc_init function. But some features
379 * such as adc_clk, resolution, tsample_cycle, we think better to set as default value,
380 * and user don't need to change them in most use cases.
381 */
382 void adc_init(adc_ref_vol_e v_ref,adc_pre_scale_e pre_scale,adc_sample_freq_e sample_freq);
383 /**
384 * @brief This function serves to start adc sample and get raw adc sample code.
385 * @param[in] sample_buffer - pointer to the buffer adc sample code need to store.
386 * @param[in] sample_num - the number of adc sample code.
387 * @return none
388 */
389 void adc_get_code_dma(unsigned short *sample_buffer, unsigned short sample_num);
390 /**
391 * @brief This function serves to directly get an adc sample code from analog registers.
392 * @return adc_code - the adc sample code.
393 */
394 unsigned short adc_get_code(void);
395 /**
396 * @brief This function serves to calculate voltage from adc sample code.
397 * @param[in] adc_code - the adc sample code.
398 * @return adc_vol_mv - the average value of adc voltage value.
399 */
400 unsigned short adc_calculate_voltage(unsigned short adc_code);
401 /**
402 * @brief This function serves to calculate temperature from temperature sensor adc sample code.
403 * @param[in] adc_code - the temperature sensor adc sample code.
404 * @return adc_temp_value - the of temperature value.
405 * attention Temperature and adc_code are linearly related. We test four chips between -40~130 (Celsius) and got an average relationship:
406 * Temp = 564 - ((adc_code * 819)>>13),when Vref = 1.2V, pre_scale = 1.
407 */
408 unsigned short adc_calculate_temperature(unsigned short adc_code);
409