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