1 /*
2 * Copyright (c) 2021-2023 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include "hpm_adc16_drv.h"
9 #include "hpm_soc_feature.h"
10
adc16_get_default_config(adc16_config_t * config)11 void adc16_get_default_config(adc16_config_t *config)
12 {
13 config->res = adc16_res_16_bits;
14 config->conv_mode = adc16_conv_mode_oneshot;
15 config->adc_clk_div = adc16_clock_divider_1;
16 config->conv_duration = 0;
17 config->wait_dis = true;
18 config->sel_sync_ahb = true;
19 config->port3_realtime = false;
20 config->adc_ahb_en = false;
21 }
22
adc16_get_channel_default_config(adc16_channel_config_t * config)23 void adc16_get_channel_default_config(adc16_channel_config_t *config)
24 {
25 config->ch = 0;
26 config->sample_cycle = 10;
27 config->sample_cycle_shift = 0;
28 config->thshdh = 0xffff;
29 config->thshdl = 0x0000;
30 config->wdog_int_en = false;
31 }
32
adc16_do_calibration(ADC16_Type * ptr)33 static hpm_stat_t adc16_do_calibration(ADC16_Type *ptr)
34 {
35 uint32_t i, j;
36 uint32_t clk_div_temp;
37 uint32_t adc16_params[ADC16_SOC_PARAMS_LEN];
38 int32_t param01;
39 uint32_t param02;
40 uint64_t param64;
41 uint32_t param32;
42 uint32_t temp;
43
44 /* Get input clock divider */
45 clk_div_temp = ADC16_CONV_CFG1_CLOCK_DIVIDER_GET(ptr->CONV_CFG1);
46
47 /* Set input clock divider temporarily */
48 ptr->CONV_CFG1 = (ptr->CONV_CFG1 & ~ADC16_CONV_CFG1_CLOCK_DIVIDER_MASK)
49 | ADC16_CONV_CFG1_CLOCK_DIVIDER_SET(1);
50
51 /* Enable ADC config clock */
52 ptr->ANA_CTRL0 |= ADC16_ANA_CTRL0_ADC_CLK_ON_MASK;
53
54 for (i = 0; i < ADC16_SOC_PARAMS_LEN; i++) {
55 adc16_params[i] = 0;
56 }
57
58 /* Enable reg_en */
59 /* Enable bandgap_en */
60 ptr->ADC16_CONFIG0 |= ADC16_ADC16_CONFIG0_REG_EN_MASK
61 | ADC16_ADC16_CONFIG0_BANDGAP_EN_MASK;
62
63 /* Set cal_avg_cfg for 32 loops */
64 ptr->ADC16_CONFIG0 = (ptr->ADC16_CONFIG0 & ~ADC16_ADC16_CONFIG0_CAL_AVG_CFG_MASK)
65 | ADC16_ADC16_CONFIG0_CAL_AVG_CFG_SET(5);
66
67 /* Enable ahb_en */
68 ptr->ADC_CFG0 |= ADC16_ADC_CFG0_ADC_AHB_EN_MASK;
69
70 /* Disable ADC config clock */
71 ptr->ANA_CTRL0 &= ~ADC16_ANA_CTRL0_ADC_CLK_ON_MASK;
72
73 /* Recover input clock divider */
74 ptr->CONV_CFG1 = (ptr->CONV_CFG1 & ~ADC16_CONV_CFG1_CLOCK_DIVIDER_MASK)
75 | ADC16_CONV_CFG1_CLOCK_DIVIDER_SET(clk_div_temp);
76
77 for (j = 0; j < 4; j++) {
78 /* Set startcal */
79 ptr->ANA_CTRL0 |= ADC16_ANA_CTRL0_STARTCAL_MASK;
80
81 /* Clear startcal */
82 ptr->ANA_CTRL0 &= ~ADC16_ANA_CTRL0_STARTCAL_MASK;
83
84 /* Polling calibration status */
85 while (ADC16_ANA_STATUS_CALON_GET(ptr->ANA_STATUS)) {
86 }
87
88 /* Read parameters */
89 for (i = 0; i < ADC16_SOC_PARAMS_LEN; i++) {
90 adc16_params[i] += ADC16_ADC16_PARAMS_PARAM_VAL_GET(ptr->ADC16_PARAMS[i]);
91 }
92 }
93
94 adc16_params[ADC16_ADC16_PARAMS_ADC16_PARA33] -= 0x800;
95 param01 = adc16_params[ADC16_ADC16_PARAMS_ADC16_PARA32] - adc16_params[ADC16_ADC16_PARAMS_ADC16_PARA33];
96 adc16_params[ADC16_ADC16_PARAMS_ADC16_PARA32] = adc16_params[ADC16_ADC16_PARAMS_ADC16_PARA00] -
97 adc16_params[ADC16_ADC16_PARAMS_ADC16_PARA33];
98 adc16_params[ADC16_ADC16_PARAMS_ADC16_PARA00] = 0;
99
100 for (i = 1; i < ADC16_SOC_PARAMS_LEN - 2; i++) {
101 adc16_params[i] = adc16_params[ADC16_ADC16_PARAMS_ADC16_PARA32] + adc16_params[i] -
102 adc16_params[ADC16_ADC16_PARAMS_ADC16_PARA33] + adc16_params[i - 1];
103 }
104
105 param02 = (param01 + adc16_params[ADC16_ADC16_PARAMS_ADC16_PARA31] + adc16_params[ADC16_ADC16_PARAMS_ADC16_PARA32]) >> 6;
106 param64 = 0x10000ll * param02;
107 param64 = param64 / (0x20000 - param02 / 2);
108 param32 = (uint32_t)param64;
109
110 for (i = 0; i < ADC16_SOC_PARAMS_LEN; i++) {
111 adc16_params[i] >>= 6;
112 }
113
114 /* Enable ADC config clock */
115 ptr->ANA_CTRL0 |= ADC16_ANA_CTRL0_ADC_CLK_ON_MASK;
116
117 ptr->CONV_CFG1 = (ptr->CONV_CFG1 & ~ADC16_CONV_CFG1_CLOCK_DIVIDER_MASK)
118 | ADC16_CONV_CFG1_CLOCK_DIVIDER_SET(1);
119
120 /* Write parameters */
121 for (i = 0; i < ADC16_SOC_PARAMS_LEN ; i++) {
122 ptr->ADC16_PARAMS[i] = (uint16_t)(adc16_params[i]);
123 }
124
125 /* Set ADC16 Config0 */
126 temp = ptr->ADC16_CONFIG0;
127
128 temp &= ~(ADC16_ADC16_CONFIG0_CAL_AVG_CFG_MASK | ADC16_ADC16_CONFIG0_CONV_PARAM_MASK);
129
130 temp |= ADC16_ADC16_CONFIG0_REG_EN_MASK
131 | ADC16_ADC16_CONFIG0_BANDGAP_EN_MASK
132 | ADC16_ADC16_CONFIG0_CAL_AVG_CFG_MASK
133 | ADC16_ADC16_CONFIG0_CONV_PARAM_SET(param32);
134
135 ptr->ADC16_CONFIG0 = temp;
136
137 /* Recover input clock divider */
138 ptr->CONV_CFG1 = (ptr->CONV_CFG1 & ~ADC16_CONV_CFG1_CLOCK_DIVIDER_MASK)
139 | ADC16_CONV_CFG1_CLOCK_DIVIDER_SET(clk_div_temp);
140
141 /* Disable ADC config clock */
142 ptr->ANA_CTRL0 &= ~ADC16_ANA_CTRL0_ADC_CLK_ON_MASK;
143
144 return status_success;
145 }
146
adc16_deinit(ADC16_Type * ptr)147 hpm_stat_t adc16_deinit(ADC16_Type *ptr)
148 {
149 /* disable all interrupts */
150 ptr->INT_EN = 0;
151
152 return status_success;
153 }
154
adc16_init(ADC16_Type * ptr,adc16_config_t * config)155 hpm_stat_t adc16_init(ADC16_Type *ptr, adc16_config_t *config)
156 {
157 uint32_t clk_div_temp;
158
159 /* Set convert clock number and clock period */
160 if (config->adc_clk_div - 1 > ADC16_CONV_CFG1_CLOCK_DIVIDER_MASK) {
161 return status_invalid_argument;
162 }
163
164 /* Set ADC minimum conversion cycle and ADC clock divider */
165 ptr->CONV_CFG1 = ADC16_CONV_CFG1_CONVERT_CLOCK_NUMBER_SET(config->res)
166 | ADC16_CONV_CFG1_CLOCK_DIVIDER_SET(config->adc_clk_div - 1);
167
168 /* Set ahb_en */
169 /* Set the duration of the conversion */
170 ptr->ADC_CFG0 = ADC16_ADC_CFG0_SEL_SYNC_AHB_SET(config->sel_sync_ahb)
171 | ADC16_ADC_CFG0_ADC_AHB_EN_SET(config->adc_ahb_en)
172 | ADC16_ADC_CFG0_CONVERT_DURATION_SET(config->conv_duration)
173 | ADC16_ADC_CFG0_PORT3_REALTIME_SET(config->port3_realtime);
174
175 /* Set wait_dis */
176 ptr->BUF_CFG0 = ADC16_BUF_CFG0_WAIT_DIS_SET(config->wait_dis);
177
178 /* Get input clock divider */
179 clk_div_temp = ADC16_CONV_CFG1_CLOCK_DIVIDER_GET(ptr->CONV_CFG1);
180
181 /* Set input clock divider temporarily */
182 ptr->CONV_CFG1 = (ptr->CONV_CFG1 & ~ADC16_CONV_CFG1_CLOCK_DIVIDER_MASK)
183 | ADC16_CONV_CFG1_CLOCK_DIVIDER_SET(1);
184
185 /* Enable ADC config clock */
186 ptr->ANA_CTRL0 |= ADC16_ANA_CTRL0_ADC_CLK_ON_MASK;
187
188 /* Set end count */
189 ptr->ADC16_CONFIG1 &= ~ADC16_ADC16_CONFIG1_COV_END_CNT_MASK;
190 ptr->ADC16_CONFIG1 |= ADC16_ADC16_CONFIG1_COV_END_CNT_SET(ADC16_SOC_MAX_CONV_CLK_NUM - config->res + 1);
191
192 /* Disable ADC config clock */
193 ptr->ANA_CTRL0 &= ~ADC16_ANA_CTRL0_ADC_CLK_ON_MASK;
194
195 /* Recover input clock divider */
196 ptr->CONV_CFG1 = (ptr->CONV_CFG1 & ~ADC16_CONV_CFG1_CLOCK_DIVIDER_MASK)
197 | ADC16_CONV_CFG1_CLOCK_DIVIDER_SET(clk_div_temp);
198
199 /* Do a calibration */
200 adc16_do_calibration(ptr);
201
202 return status_success;
203 }
204
adc16_init_channel(ADC16_Type * ptr,adc16_channel_config_t * config)205 hpm_stat_t adc16_init_channel(ADC16_Type *ptr, adc16_channel_config_t *config)
206 {
207 /* Check the specified channel number */
208 if (ADC16_IS_CHANNEL_INVALID(config->ch)) {
209 return status_invalid_argument;
210 }
211
212 /* Set warning threshold */
213 ptr->PRD_CFG[config->ch].PRD_THSHD_CFG = ADC16_PRD_CFG_PRD_THSHD_CFG_THSHDH_SET(config->thshdh)
214 | ADC16_PRD_CFG_PRD_THSHD_CFG_THSHDL_SET(config->thshdl);
215
216 /* Set ADC sample cycles multiple */
217 /* Set ADC sample cycles */
218 ptr->SAMPLE_CFG[config->ch] = ADC16_SAMPLE_CFG_SAMPLE_CLOCK_NUMBER_SHIFT_SET(config->sample_cycle_shift)
219 | ADC16_SAMPLE_CFG_SAMPLE_CLOCK_NUMBER_SET(config->sample_cycle);
220
221 /* Enable watchdog interrupt */
222 if (config->wdog_int_en) {
223 ptr->INT_EN |= 1 << config->ch;
224 }
225
226 return status_success;
227 }
228
adc16_get_channel_threshold(ADC16_Type * ptr,uint8_t ch,adc16_channel_threshold_t * config)229 hpm_stat_t adc16_get_channel_threshold(ADC16_Type *ptr, uint8_t ch, adc16_channel_threshold_t *config)
230 {
231 /* Check the specified channel number */
232 if (ADC16_IS_CHANNEL_INVALID(ch)) {
233 return status_invalid_argument;
234 }
235
236 config->ch = ch;
237 config->thshdh = ADC16_PRD_CFG_PRD_THSHD_CFG_THSHDH_GET(ptr->PRD_CFG[ch].PRD_THSHD_CFG);
238 config->thshdl = ADC16_PRD_CFG_PRD_THSHD_CFG_THSHDL_GET(ptr->PRD_CFG[ch].PRD_THSHD_CFG);
239
240 return status_success;
241 }
242
243 #if defined(ADC_SOC_BUSMODE_ENABLE_CTRL_SUPPORT) && ADC_SOC_BUSMODE_ENABLE_CTRL_SUPPORT
adc16_enable_oneshot_mode(ADC16_Type * ptr)244 void adc16_enable_oneshot_mode(ADC16_Type *ptr)
245 {
246 ptr->BUF_CFG0 |= ADC16_BUF_CFG0_BUS_MODE_EN_MASK;
247 }
248
adc16_disable_oneshot_mode(ADC16_Type * ptr)249 void adc16_disable_oneshot_mode(ADC16_Type *ptr)
250 {
251 ptr->BUF_CFG0 &= ~ADC16_BUF_CFG0_BUS_MODE_EN_MASK;
252 }
253 #endif
254
adc16_init_seq_dma(ADC16_Type * ptr,adc16_dma_config_t * dma_config)255 hpm_stat_t adc16_init_seq_dma(ADC16_Type *ptr, adc16_dma_config_t *dma_config)
256 {
257 /* Check the DMA buffer length */
258 if (ADC16_IS_SEQ_DMA_BUFF_LEN_INVLAID(dma_config->buff_len_in_4bytes)) {
259 return status_invalid_argument;
260 }
261
262 /* Reset ADC DMA */
263 ptr->SEQ_DMA_CFG |= ADC16_SEQ_DMA_CFG_DMA_RST_MASK;
264
265 /* Reset memory to clear all of cycle bits */
266 memset(dma_config->start_addr, 0x00, dma_config->buff_len_in_4bytes * sizeof(uint32_t));
267
268 /* De-reset ADC DMA */
269 ptr->SEQ_DMA_CFG &= ~ADC16_SEQ_DMA_CFG_DMA_RST_MASK;
270
271 /* Set ADC DMA target address which should be 4-byte aligned */
272 ptr->SEQ_DMA_ADDR = (uint32_t)dma_config->start_addr & ADC16_SEQ_DMA_ADDR_TAR_ADDR_MASK;
273
274 /* Set ADC DMA memory dword length */
275 ptr->SEQ_DMA_CFG = (ptr->SEQ_DMA_CFG & ~ADC16_SEQ_DMA_CFG_BUF_LEN_MASK)
276 | ADC16_SEQ_DMA_CFG_BUF_LEN_SET(dma_config->buff_len_in_4bytes - 1);
277
278 #if defined(ADC_SOC_SEQ_HCFG_EN) && ADC_SOC_SEQ_HCFG_EN
279 /* Set high-half buffer length */
280 ptr->SEQ_HIGH_CFG = (ptr->SEQ_HIGH_CFG & ~ADC16_SEQ_HIGH_CFG_BUF_LEN_HIGH_MASK)
281 | ADC16_SEQ_HIGH_CFG_BUF_LEN_HIGH_SET(((dma_config->buff_len_in_4bytes - 1) >> 12));
282 #endif
283
284 /* Set stop_en and stop_pos */
285 if (dma_config->stop_en) {
286 ptr->SEQ_DMA_CFG = (ptr->SEQ_DMA_CFG & ~ADC16_SEQ_DMA_CFG_STOP_POS_MASK)
287 | ADC16_SEQ_DMA_CFG_STOP_EN_MASK
288 | ADC16_SEQ_DMA_CFG_STOP_POS_SET(dma_config->stop_pos);
289
290 #if defined(ADC_SOC_SEQ_HCFG_EN) && ADC_SOC_SEQ_HCFG_EN
291 ptr->SEQ_HIGH_CFG = (ptr->SEQ_HIGH_CFG & ~ADC16_SEQ_HIGH_CFG_STOP_POS_HIGH_MASK)
292 | ADC16_SEQ_HIGH_CFG_STOP_POS_HIGH_SET(((dma_config->stop_pos) >> 12));
293 #endif
294 }
295
296 return status_success;
297 }
298
adc16_set_prd_config(ADC16_Type * ptr,adc16_prd_config_t * config)299 hpm_stat_t adc16_set_prd_config(ADC16_Type *ptr, adc16_prd_config_t *config)
300 {
301 /* Check the specified channel number */
302 if (ADC16_IS_CHANNEL_INVALID(config->ch)) {
303 return status_invalid_argument;
304 }
305
306 /* Check the prescale */
307 if (config->prescale > (ADC16_PRD_CFG_PRD_CFG_PRESCALE_MASK >> ADC16_PRD_CFG_PRD_CFG_PRESCALE_SHIFT)) {
308 return status_invalid_argument;
309 }
310
311 /* Set periodic prescale */
312 ptr->PRD_CFG[config->ch].PRD_CFG = (ptr->PRD_CFG[config->ch].PRD_CFG & ~ADC16_PRD_CFG_PRD_CFG_PRESCALE_MASK)
313 | ADC16_PRD_CFG_PRD_CFG_PRESCALE_SET(config->prescale);
314
315 /* Set period count */
316 ptr->PRD_CFG[config->ch].PRD_CFG = (ptr->PRD_CFG[config->ch].PRD_CFG & ~ADC16_PRD_CFG_PRD_CFG_PRD_MASK)
317 | ADC16_PRD_CFG_PRD_CFG_PRD_SET(config->period_count);
318
319 return status_success;
320 }
321
adc16_trigger_seq_by_sw(ADC16_Type * ptr)322 hpm_stat_t adc16_trigger_seq_by_sw(ADC16_Type *ptr)
323 {
324 if (ADC16_INT_STS_SEQ_SW_CFLCT_GET(ptr->INT_STS)) {
325 return status_fail;
326 }
327 ptr->SEQ_CFG0 |= ADC16_SEQ_CFG0_SW_TRIG_MASK;
328
329 return status_success;
330 }
331
332 /* Note: the sequence length can not be larger or equal than 2 in HPM6750EVK Revision A0 */
adc16_set_seq_config(ADC16_Type * ptr,adc16_seq_config_t * config)333 hpm_stat_t adc16_set_seq_config(ADC16_Type *ptr, adc16_seq_config_t *config)
334 {
335 /* Check sequence length */
336 if (ADC16_IS_SEQ_LEN_INVLAID(config->seq_len)) {
337 return status_invalid_argument;
338 }
339
340 ptr->SEQ_CFG0 = ADC16_SEQ_CFG0_SEQ_LEN_SET(config->seq_len - 1)
341 | ADC16_SEQ_CFG0_RESTART_EN_SET(config->restart_en)
342 | ADC16_SEQ_CFG0_CONT_EN_SET(config->cont_en)
343 | ADC16_SEQ_CFG0_SW_TRIG_EN_SET(config->sw_trig_en)
344 | ADC16_SEQ_CFG0_HW_TRIG_EN_SET(config->hw_trig_en);
345
346 /* Set sequence queue */
347 for (int i = 0; i < config->seq_len; i++) {
348 /* Check the specified channel number */
349 if (ADC16_IS_CHANNEL_INVALID(config->queue[i].ch)) {
350 return status_invalid_argument;
351 }
352
353 ptr->SEQ_QUE[i] = ADC16_SEQ_QUE_SEQ_INT_EN_SET(config->queue[i].seq_int_en)
354 | ADC16_SEQ_QUE_CHAN_NUM_4_0_SET(config->queue[i].ch);
355 }
356
357 return status_success;
358 }
359
adc16_trigger_pmt_by_sw(ADC16_Type * ptr,uint8_t trig_ch)360 hpm_stat_t adc16_trigger_pmt_by_sw(ADC16_Type *ptr, uint8_t trig_ch)
361 {
362 ptr->TRG_SW_STA = ADC16_TRG_SW_STA_TRG_SW_STA_MASK | ADC16_TRG_SW_STA_TRIG_SW_INDEX_SET(trig_ch);
363
364 return status_success;
365 }
366
adc16_set_pmt_config(ADC16_Type * ptr,adc16_pmt_config_t * config)367 hpm_stat_t adc16_set_pmt_config(ADC16_Type *ptr, adc16_pmt_config_t *config)
368 {
369 uint32_t temp = 0;
370
371 /* Check the specified trigger length */
372 if (ADC16_IS_TRIG_LEN_INVLAID(config->trig_len)) {
373 return status_invalid_argument;
374 }
375
376 /* Check the triggier channel */
377 if (ADC16_IS_TRIG_CH_INVLAID(config->trig_ch)) {
378 return status_invalid_argument;
379 }
380
381 temp |= ADC16_CONFIG_TRIG_LEN_SET(config->trig_len - 1);
382
383 for (int i = 0; i < config->trig_len; i++) {
384 if (ADC16_IS_CHANNEL_INVALID(config->adc_ch[i])) {
385 return status_invalid_argument;
386 }
387
388 temp |= config->inten[i] << (ADC16_CONFIG_INTEN0_SHIFT + i * ADC_SOC_CONFIG_INTEN_CHAN_BIT_SIZE)
389 | config->adc_ch[i] << (ADC16_CONFIG_CHAN0_SHIFT + i * ADC_SOC_CONFIG_INTEN_CHAN_BIT_SIZE);
390 }
391
392 ptr->CONFIG[config->trig_ch] = temp;
393
394 return status_success;
395 }
396
adc16_set_pmt_queue_enable(ADC16_Type * ptr,uint8_t trig_ch,bool enable)397 hpm_stat_t adc16_set_pmt_queue_enable(ADC16_Type *ptr, uint8_t trig_ch, bool enable)
398 {
399 (void) ptr;
400 /* Check the specified trigger channel */
401 if (ADC16_IS_TRIG_CH_INVLAID(trig_ch)) {
402 return status_invalid_argument;
403 }
404
405 #if ADC_SOC_PREEMPT_ENABLE_CTRL_SUPPORT == 1
406 /* Set queue enable control */
407 ptr->CONFIG[trig_ch] |= ADC16_CONFIG_QUEUE_EN_SET(enable);
408 return status_success;
409 #else
410 (void) enable;
411 return status_success;
412 #endif
413 }
414
415 /* one shot mode */
adc16_get_oneshot_result(ADC16_Type * ptr,uint8_t ch,uint16_t * result)416 hpm_stat_t adc16_get_oneshot_result(ADC16_Type *ptr, uint8_t ch, uint16_t *result)
417 {
418 uint32_t bus_res;
419
420 /* Check the specified channel number */
421 if (ADC16_IS_CHANNEL_INVALID(ch)) {
422 return status_invalid_argument;
423 }
424
425 bus_res = ptr->BUS_RESULT[ch];
426 *result = ADC16_BUS_RESULT_CHAN_RESULT_GET(bus_res);
427
428 if (ADC16_BUF_CFG0_WAIT_DIS_GET(ptr->BUF_CFG0)) {
429 if (!ADC16_BUS_RESULT_VALID_GET(bus_res)) {
430 return status_fail;
431 }
432 }
433
434 return status_success;
435 }
436
437 /* period mode */
adc16_get_prd_result(ADC16_Type * ptr,uint8_t ch,uint16_t * result)438 hpm_stat_t adc16_get_prd_result(ADC16_Type *ptr, uint8_t ch, uint16_t *result)
439 {
440 /* Check the specified channel number */
441 if (ADC16_IS_CHANNEL_INVALID(ch)) {
442 return status_invalid_argument;
443 }
444
445 *result = ADC16_PRD_CFG_PRD_RESULT_CHAN_RESULT_GET(ptr->PRD_CFG[ch].PRD_RESULT);
446
447 return status_success;
448 }
449
450 #if defined(ADC16_SOC_TEMP_CH_EN) && ADC16_SOC_TEMP_CH_EN
adc16_enable_temp_sensor(ADC16_Type * ptr)451 void adc16_enable_temp_sensor(ADC16_Type *ptr)
452 {
453 uint32_t clk_div_temp;
454
455 /* Get input clock divider */
456 clk_div_temp = ADC16_CONV_CFG1_CLOCK_DIVIDER_GET(ptr->CONV_CFG1);
457
458 /* Set input clock divider temporarily */
459 ptr->CONV_CFG1 = (ptr->CONV_CFG1 & ~ADC16_CONV_CFG1_CLOCK_DIVIDER_MASK) | ADC16_CONV_CFG1_CLOCK_DIVIDER_SET(1);
460
461 /* Enable ADC config clock */
462 ptr->ANA_CTRL0 |= ADC16_ANA_CTRL0_ADC_CLK_ON_MASK;
463
464 /* Enable the temperature sensor */
465 ptr->ADC16_CONFIG0 |= ADC16_ADC16_CONFIG0_TEMPSNS_EN_MASK | ADC16_ADC16_CONFIG0_REG_EN_MASK
466 | ADC16_ADC16_CONFIG0_BANDGAP_EN_MASK | ADC16_ADC16_CONFIG0_CAL_AVG_CFG_SET(5);
467
468 /* Disable ADC config clock */
469 ptr->ANA_CTRL0 &= ~ADC16_ANA_CTRL0_ADC_CLK_ON_MASK;
470
471 /* Recover input clock divider */
472 ptr->CONV_CFG1 = (ptr->CONV_CFG1 & ~ADC16_CONV_CFG1_CLOCK_DIVIDER_MASK) | ADC16_CONV_CFG1_CLOCK_DIVIDER_SET(clk_div_temp);
473 }
474
adc16_disable_temp_sensor(ADC16_Type * ptr)475 void adc16_disable_temp_sensor(ADC16_Type *ptr)
476 {
477 uint32_t clk_div_temp;
478
479 /* Get input clock divider */
480 clk_div_temp = ADC16_CONV_CFG1_CLOCK_DIVIDER_GET(ptr->CONV_CFG1);
481
482 /* Set input clock divider temporarily */
483 ptr->CONV_CFG1 = (ptr->CONV_CFG1 & ~ADC16_CONV_CFG1_CLOCK_DIVIDER_MASK)
484 | ADC16_CONV_CFG1_CLOCK_DIVIDER_SET(1);
485
486 /* Enable ADC config clock */
487 ptr->ANA_CTRL0 |= ADC16_ANA_CTRL0_ADC_CLK_ON_MASK;
488
489 /* Disable the temp sensor */
490 ptr->ADC16_CONFIG0 &= ~ADC16_ADC16_CONFIG0_TEMPSNS_EN_MASK;
491
492 /* Disable ADC config clock */
493 ptr->ANA_CTRL0 &= ~ADC16_ANA_CTRL0_ADC_CLK_ON_MASK;
494
495 /* Recover input clock divider */
496 ptr->CONV_CFG1 = (ptr->CONV_CFG1 & ~ADC16_CONV_CFG1_CLOCK_DIVIDER_MASK)
497 | ADC16_CONV_CFG1_CLOCK_DIVIDER_SET(clk_div_temp);
498 }
499 #endif
500