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