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