1 /*!
2 \file gd32f3x0_adc.c
3 \brief ADC driver
4
5 \version 2017-06-06, V1.0.0, firmware for GD32F3x0
6 \version 2019-06-01, V2.0.0, firmware for GD32F3x0
7 \version 2020-09-30, V2.1.0, firmware for GD32F3x0
8 */
9
10 /*
11 Copyright (c) 2020, GigaDevice Semiconductor Inc.
12
13 Redistribution and use in source and binary forms, with or without modification,
14 are permitted provided that the following conditions are met:
15
16 1. Redistributions of source code must retain the above copyright notice, this
17 list of conditions and the following disclaimer.
18 2. Redistributions in binary form must reproduce the above copyright notice,
19 this list of conditions and the following disclaimer in the documentation
20 and/or other materials provided with the distribution.
21 3. Neither the name of the copyright holder nor the names of its contributors
22 may be used to endorse or promote products derived from this software without
23 specific prior written permission.
24
25 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
29 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
34 OF SUCH DAMAGE.
35 */
36
37 #include "gd32f3x0_adc.h"
38
39 /*!
40 \brief reset ADC
41 \param[in] none
42 \param[out] none
43 \retval none
44 */
adc_deinit(void)45 void adc_deinit(void)
46 {
47 rcu_periph_reset_enable(RCU_ADCRST);
48 rcu_periph_reset_disable(RCU_ADCRST);
49 }
50
51 /*!
52 \brief enable ADC interface
53 \param[in] none
54 \param[out] none
55 \retval none
56 */
adc_enable(void)57 void adc_enable(void)
58 {
59 if(RESET == (ADC_CTL1 & ADC_CTL1_ADCON)){
60 ADC_CTL1 |= (uint32_t)ADC_CTL1_ADCON;
61 }
62 }
63
64 /*!
65 \brief disable ADC interface
66 \param[in] none
67 \param[out] none
68 \retval none
69 */
adc_disable(void)70 void adc_disable(void)
71 {
72 ADC_CTL1 &= ~((uint32_t)ADC_CTL1_ADCON);
73 }
74
75 /*!
76 \brief ADC calibration and reset calibration
77 \param[in] none
78 \param[out] none
79 \retval none
80 */
adc_calibration_enable(void)81 void adc_calibration_enable(void)
82 {
83 /* reset the selected ADC calibration register */
84 ADC_CTL1 |= (uint32_t) ADC_CTL1_RSTCLB;
85 /* check the RSTCLB bit state */
86 while((ADC_CTL1 & ADC_CTL1_RSTCLB)){
87 }
88
89 /* enable ADC calibration process */
90 ADC_CTL1 |= ADC_CTL1_CLB;
91 /* check the CLB bit state */
92 while((ADC_CTL1 & ADC_CTL1_CLB)){
93 }
94 }
95
96 /*!
97 \brief enable DMA request
98 \param[in] none
99 \param[out] none
100 \retval none
101 */
adc_dma_mode_enable(void)102 void adc_dma_mode_enable(void)
103 {
104 ADC_CTL1 |= (uint32_t)(ADC_CTL1_DMA);
105 }
106
107 /*!
108 \brief disable DMA request
109 \param[in] none
110 \param[out] none
111 \retval none
112 */
adc_dma_mode_disable(void)113 void adc_dma_mode_disable(void)
114 {
115 ADC_CTL1 &= ~((uint32_t)ADC_CTL1_DMA);
116 }
117
118 /*!
119 \brief enable the temperature sensor and Vrefint channel
120 \param[in] none
121 \param[out] none
122 \retval none
123 */
adc_tempsensor_vrefint_enable(void)124 void adc_tempsensor_vrefint_enable(void)
125 {
126 /* enable the temperature sensor and Vrefint channel */
127 ADC_CTL1 |= ADC_CTL1_TSVREN;
128 }
129
130 /*!
131 \brief disable the temperature sensor and Vrefint channel
132 \param[in] none
133 \param[out] none
134 \retval none
135 */
adc_tempsensor_vrefint_disable(void)136 void adc_tempsensor_vrefint_disable(void)
137 {
138 /* disable the temperature sensor and Vrefint channel */
139 ADC_CTL1 &= ~ADC_CTL1_TSVREN;
140 }
141
142 /*!
143 \brief enable the Vbat channel
144 \param[in] none
145 \param[out] none
146 \retval none
147 */
adc_vbat_enable(void)148 void adc_vbat_enable(void)
149 {
150 /* enable the vbat channel */
151 ADC_CTL1 |= ADC_CTL1_VBETEN;
152 }
153
154 /*!
155 \brief disable the Vbat channel
156 \param[in] none
157 \param[out] none
158 \retval none
159 */
adc_vbat_disable(void)160 void adc_vbat_disable(void)
161 {
162 /* disable the vbat channel */
163 ADC_CTL1 &= ~ADC_CTL1_VBETEN;
164 }
165
166 /*!
167 \brief configure ADC discontinuous mode
168 \param[in] channel_group: select the channel group
169 only one parameter can be selected which is shown as below:
170 \arg ADC_REGULAR_CHANNEL: regular channel group
171 \arg ADC_INSERTED_CHANNEL: inserted channel group
172 \arg ADC_CHANNEL_DISCON_DISABLE: disable discontinuous mode of regular and inserted channel
173 \param[in] length: number of conversions in discontinuous mode,the number can be 1..8
174 for regular channel, the number has no effect for inserted channel
175 \param[out] none
176 \retval none
177 */
adc_discontinuous_mode_config(uint8_t channel_group,uint8_t length)178 void adc_discontinuous_mode_config(uint8_t channel_group, uint8_t length)
179 {
180 ADC_CTL0 &= ~((uint32_t)(ADC_CTL0_DISRC | ADC_CTL0_DISIC));
181
182 switch(channel_group){
183 case ADC_REGULAR_CHANNEL:
184 /* configure the number of conversions in discontinuous mode */
185 ADC_CTL0 &= ~((uint32_t)ADC_CTL0_DISNUM);
186 ADC_CTL0 |= CTL0_DISNUM(((uint32_t)length - 1U));
187 ADC_CTL0 |= (uint32_t)ADC_CTL0_DISRC;
188 break;
189 case ADC_INSERTED_CHANNEL:
190 ADC_CTL0 |= (uint32_t)ADC_CTL0_DISIC;
191 break;
192 case ADC_CHANNEL_DISCON_DISABLE:
193 default:
194 break;
195 }
196 }
197
198 /*!
199 \brief configure ADC special function
200 \param[in] function: the function to configure
201 one or more parameters can be selected which is shown as below:
202 \arg ADC_SCAN_MODE: scan mode select
203 \arg ADC_INSERTED_CHANNEL_AUTO: inserted channel group convert automatically
204 \arg ADC_CONTINUOUS_MODE: continuous mode select
205 \param[in] newvalue: ENABLE or DISABLE
206 \param[out] none
207 \retval none
208 */
adc_special_function_config(uint32_t function,ControlStatus newvalue)209 void adc_special_function_config(uint32_t function, ControlStatus newvalue)
210 {
211 if(newvalue){
212 /* enable ADC scan mode */
213 if(RESET != (function & ADC_SCAN_MODE)){
214 ADC_CTL0 |= ADC_SCAN_MODE;
215 }
216 /* enable ADC inserted channel group convert automatically */
217 if(RESET != (function & ADC_INSERTED_CHANNEL_AUTO)){
218 ADC_CTL0 |= ADC_INSERTED_CHANNEL_AUTO;
219 }
220 /* enable ADC continuous mode */
221 if(RESET != (function & ADC_CONTINUOUS_MODE)){
222 ADC_CTL1 |= ADC_CONTINUOUS_MODE;
223 }
224 }else{
225 /* disable ADC scan mode */
226 if(RESET != (function & ADC_SCAN_MODE)){
227 ADC_CTL0 &= ~ADC_SCAN_MODE;
228 }
229 /* disable ADC inserted channel group convert automatically */
230 if(RESET != (function & ADC_INSERTED_CHANNEL_AUTO)){
231 ADC_CTL0 &= ~ADC_INSERTED_CHANNEL_AUTO;
232 }
233 /* disable ADC continuous mode */
234 if(RESET != (function & ADC_CONTINUOUS_MODE)){
235 ADC_CTL1 &= ~ADC_CONTINUOUS_MODE;
236 }
237 }
238 }
239
240 /*!
241 \brief configure ADC data alignment
242 \param[in] data_alignment: data alignment select
243 only one parameter can be selected which is shown as below:
244 \arg ADC_DATAALIGN_RIGHT: right alignment
245 \arg ADC_DATAALIGN_LEFT: left alignment
246 \param[out] none
247 \retval none
248 */
adc_data_alignment_config(uint32_t data_alignment)249 void adc_data_alignment_config(uint32_t data_alignment)
250 {
251 if(ADC_DATAALIGN_RIGHT != data_alignment){
252 ADC_CTL1 |= ADC_CTL1_DAL;
253 }else{
254 ADC_CTL1 &= ~((uint32_t)ADC_CTL1_DAL);
255 }
256 }
257
258 /*!
259 \brief configure the length of regular channel group or inserted channel group
260 \param[in] channel_group: select the channel group
261 only one parameter can be selected which is shown as below:
262 \arg ADC_REGULAR_CHANNEL: regular channel group
263 \arg ADC_INSERTED_CHANNEL: inserted channel group
264 \param[in] length: the length of the channel
265 regular channel 1-16
266 inserted channel 1-4
267 \param[out] none
268 \retval none
269 */
adc_channel_length_config(uint8_t channel_group,uint32_t length)270 void adc_channel_length_config(uint8_t channel_group, uint32_t length)
271 {
272 switch(channel_group){
273 case ADC_REGULAR_CHANNEL:
274 /* configure the length of regular channel group */
275 ADC_RSQ0 &= ~((uint32_t)ADC_RSQ0_RL);
276 ADC_RSQ0 |= RSQ0_RL((uint32_t)(length-1U));
277 break;
278 case ADC_INSERTED_CHANNEL:
279 /* configure the length of inserted channel group */
280 ADC_ISQ &= ~((uint32_t)ADC_ISQ_IL);
281 ADC_ISQ |= ISQ_IL((uint32_t)(length-1U));
282 break;
283 default:
284 break;
285 }
286 }
287
288 /*!
289 \brief configure ADC regular channel
290 \param[in] rank: the regular group sequence rank, this parameter must be between 0 to 15
291 \param[in] channel: the selected ADC channel
292 only one parameter can be selected which is shown as below:
293 \arg ADC_CHANNEL_x(x=0..18): ADC Channelx
294 \param[in] sample_time: the sample time value
295 only one parameter can be selected which is shown as below:
296 \arg ADC_SAMPLETIME_1POINT5: 1.5 cycles
297 \arg ADC_SAMPLETIME_7POINT5: 7.5 cycles
298 \arg ADC_SAMPLETIME_13POINT5: 13.5 cycles
299 \arg ADC_SAMPLETIME_28POINT5: 28.5 cycles
300 \arg ADC_SAMPLETIME_41POINT5: 41.5 cycles
301 \arg ADC_SAMPLETIME_55POINT5: 55.5 cycles
302 \arg ADC_SAMPLETIME_71POINT5: 71.5 cycles
303 \arg ADC_SAMPLETIME_239POINT5: 239.5 cycles
304 \param[out] none
305 \retval none
306 */
adc_regular_channel_config(uint8_t rank,uint8_t channel,uint32_t sample_time)307 void adc_regular_channel_config(uint8_t rank, uint8_t channel, uint32_t sample_time)
308 {
309 uint32_t rsq,sampt;
310
311 /* configure ADC regular sequence */
312 if(rank < 6U){
313 rsq = ADC_RSQ2;
314 rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*rank)));
315 rsq |= ((uint32_t)channel << (5U*rank));
316 ADC_RSQ2 = rsq;
317 }else if(rank < 12U){
318 rsq = ADC_RSQ1;
319 rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*(rank-6U))));
320 rsq |= ((uint32_t)channel << (5U*(rank-6U)));
321 ADC_RSQ1 = rsq;
322 }else if(rank < 16U){
323 rsq = ADC_RSQ0;
324 rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*(rank-12U))));
325 rsq |= ((uint32_t)channel << (5U*(rank-12U)));
326 ADC_RSQ0 = rsq;
327 }else{
328 }
329
330 /* configure ADC sampling time */
331 if(channel < 10U){
332 sampt = ADC_SAMPT1;
333 sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*channel)));
334 sampt |= (uint32_t)(sample_time << (3U*channel));
335 ADC_SAMPT1 = sampt;
336 }else if(channel < 19U){
337 sampt = ADC_SAMPT0;
338 sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*(channel-10U))));
339 sampt |= (uint32_t)(sample_time << (3U*(channel-10U)));
340 ADC_SAMPT0 = sampt;
341 }else{
342 /* illegal parameters */
343 }
344 }
345
346 /*!
347 \brief configure ADC inserted channel
348 \param[in] rank: the inserted group sequencer rank,this parameter must be between 0 to 3
349 \param[in] channel: the selected ADC channel
350 only one parameter can be selected which is shown as below:
351 \arg ADC_CHANNEL_x(x=0..18): ADC Channelx
352 \param[in] sample_time: The sample time value
353 only one parameter can be selected which is shown as below:
354 \arg ADC_SAMPLETIME_1POINT5: 1.5 cycles
355 \arg ADC_SAMPLETIME_7POINT5: 7.5 cycles
356 \arg ADC_SAMPLETIME_13POINT5: 13.5 cycles
357 \arg ADC_SAMPLETIME_28POINT5: 28.5 cycles
358 \arg ADC_SAMPLETIME_41POINT5: 41.5 cycles
359 \arg ADC_SAMPLETIME_55POINT5: 55.5 cycles
360 \arg ADC_SAMPLETIME_71POINT5: 71.5 cycles
361 \arg ADC_SAMPLETIME_239POINT5: 239.5 cycles
362 \param[out] none
363 \retval none
364 */
adc_inserted_channel_config(uint8_t rank,uint8_t channel,uint32_t sample_time)365 void adc_inserted_channel_config(uint8_t rank, uint8_t channel, uint32_t sample_time)
366 {
367 uint8_t inserted_length;
368 uint32_t isq,sampt;
369
370 inserted_length = (uint8_t)GET_BITS(ADC_ISQ , 20U , 21U);
371
372 isq = ADC_ISQ;
373 isq &= ~((uint32_t)(ADC_ISQ_ISQN << (15U - (inserted_length - rank)*5U)));
374 isq |= ((uint32_t)channel << (15U - (inserted_length - rank)*5U));
375 ADC_ISQ = isq;
376
377 /* configure ADC sampling time */
378 if(channel < 10U){
379 sampt = ADC_SAMPT1;
380 sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*channel)));
381 sampt |= (uint32_t) sample_time << (3U*channel);
382 ADC_SAMPT1 = sampt;
383 }else if(channel < 19U){
384 sampt = ADC_SAMPT0;
385 sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*(channel - 10U))));
386 sampt |= ((uint32_t)sample_time << (3U*(channel - 10U)));
387 ADC_SAMPT0 = sampt;
388 }else{
389 /* illegal parameters */
390 }
391 }
392
393 /*!
394 \brief configure ADC inserted channel offset
395 \param[in] inserted_channel: insert channel select
396 only one parameter can be selected which is shown as below:
397 \arg ADC_INSERTED_CHANNEL_0: ADC inserted channel 0
398 \arg ADC_INSERTED_CHANNEL_1: ADC inserted channel 1
399 \arg ADC_INSERTED_CHANNEL_2: ADC inserted channel 2
400 \arg ADC_INSERTED_CHANNEL_3: ADC inserted channel 3
401 \param[in] offset: the offset data
402 \param[out] none
403 \retval none
404 */
adc_inserted_channel_offset_config(uint8_t inserted_channel,uint16_t offset)405 void adc_inserted_channel_offset_config(uint8_t inserted_channel, uint16_t offset)
406 {
407 uint8_t inserted_length;
408 uint32_t num = 0U;
409
410 inserted_length = (uint8_t)GET_BITS(ADC_ISQ, 20U, 21U);
411 num = 3U - (inserted_length - inserted_channel);
412
413 if(num <= 3U){
414 /* calculate the offset of the register */
415 num = num * 4U;
416 /* configure the offset of the selected channels */
417 REG32((ADC) + 0x14U + num) = IOFFX_IOFF((uint32_t)offset);
418 }
419 }
420
421 /*!
422 \brief enable or disable ADC external trigger
423 \param[in] channel_group: select the channel group
424 one or more parameters can be selected which is shown as below:
425 \arg ADC_REGULAR_CHANNEL: regular channel group
426 \arg ADC_INSERTED_CHANNEL: inserted channel group
427 \param[in] newvalue: ENABLE or DISABLE
428 \param[out] none
429 \retval none
430 */
adc_external_trigger_config(uint8_t channel_group,ControlStatus newvalue)431 void adc_external_trigger_config(uint8_t channel_group, ControlStatus newvalue)
432 {
433 if(newvalue){
434 /* external trigger enable for regular channel */
435 if(RESET != (channel_group & ADC_REGULAR_CHANNEL)){
436 ADC_CTL1 |= ADC_CTL1_ETERC;
437 }
438 /* external trigger enable for inserted channel */
439 if(RESET != (channel_group & ADC_INSERTED_CHANNEL)){
440 ADC_CTL1 |= ADC_CTL1_ETEIC;
441 }
442 }else{
443 /* external trigger disable for regular channel */
444 if(RESET != (channel_group & ADC_REGULAR_CHANNEL)){
445 ADC_CTL1 &= ~ADC_CTL1_ETERC;
446 }
447 /* external trigger disable for inserted channel */
448 if(RESET != (channel_group & ADC_INSERTED_CHANNEL)){
449 ADC_CTL1 &= ~ADC_CTL1_ETEIC;
450 }
451 }
452 }
453
454 /*!
455 \brief configure ADC external trigger source
456 \param[in] channel_group: select the channel group
457 only one parameter can be selected which is shown as below:
458 \arg ADC_REGULAR_CHANNEL: regular channel group
459 \arg ADC_INSERTED_CHANNEL: inserted channel group
460 \param[in] external_trigger_source: regular or inserted group trigger source
461 only one parameter can be selected which is shown as below:
462 for regular channel:
463 \arg ADC_EXTTRIG_REGULAR_T0_CH0: TIMER0 CH0 event select
464 \arg ADC_EXTTRIG_REGULAR_T0_CH1: TIMER0 CH1 event select
465 \arg ADC_EXTTRIG_REGULAR_T0_CH2: TIMER0 CH2 event select
466 \arg ADC_EXTTRIG_REGULAR_T1_CH1: TIMER1 CH1 event select
467 \arg ADC_EXTTRIG_REGULAR_T2_TRGO: TIMER2 TRGO event select
468 \arg ADC_EXTTRIG_REGULAR_T14_CH0: TIMER14 CH0 event select
469 \arg ADC_EXTTRIG_REGULAR_EXTI_11: external interrupt line 11
470 \arg ADC_EXTTRIG_REGULAR_NONE: software trigger
471 for inserted channel:
472 \arg ADC_EXTTRIG_INSERTED_T0_TRGO: TIMER0 TRGO event select
473 \arg ADC_EXTTRIG_INSERTED_T0_CH3: TIMER0 CH3 event select
474 \arg ADC_EXTTRIG_INSERTED_T1_TRGO: TIMER1 TRGO event select
475 \arg ADC_EXTTRIG_INSERTED_T1_CH0: TIMER1 CH0 event select
476 \arg ADC_EXTTRIG_INSERTED_T2_CH3: TIMER2 CH3 event select
477 \arg ADC_EXTTRIG_INSERTED_T14_TRGO: TIMER14 TRGO event select
478 \arg ADC_EXTTRIG_INSERTED_EXTI_15: external interrupt line 15
479 \arg ADC_EXTTRIG_INSERTED_NONE: software trigger
480 \param[out] none
481 \retval none
482 */
adc_external_trigger_source_config(uint8_t channel_group,uint32_t external_trigger_source)483 void adc_external_trigger_source_config(uint8_t channel_group, uint32_t external_trigger_source)
484 {
485 switch(channel_group){
486 case ADC_REGULAR_CHANNEL:
487 /* external trigger select for regular channel */
488 ADC_CTL1 &= ~((uint32_t)ADC_CTL1_ETSRC);
489 ADC_CTL1 |= (uint32_t)external_trigger_source;
490 break;
491 case ADC_INSERTED_CHANNEL:
492 /* external trigger select for inserted channel */
493 ADC_CTL1 &= ~((uint32_t)ADC_CTL1_ETSIC);
494 ADC_CTL1 |= (uint32_t)external_trigger_source;
495 break;
496 default:
497 break;
498 }
499 }
500
501 /*!
502 \brief enable ADC software trigger
503 \param[in] channel_group: select the channel group
504 one or more parameters can be selected which is shown as below:
505 \arg ADC_REGULAR_CHANNEL: regular channel group
506 \arg ADC_INSERTED_CHANNEL: inserted channel group
507 \param[out] none
508 \retval none
509 */
adc_software_trigger_enable(uint8_t channel_group)510 void adc_software_trigger_enable(uint8_t channel_group)
511 {
512 /* enable regular group channel software trigger */
513 if(RESET != (channel_group & ADC_REGULAR_CHANNEL)){
514 ADC_CTL1 |= ADC_CTL1_SWRCST;
515 }
516 /* enable inserted channel group software trigger */
517 if(RESET != (channel_group & ADC_INSERTED_CHANNEL)){
518 ADC_CTL1 |= ADC_CTL1_SWICST;
519 }
520 }
521
522 /*!
523 \brief read ADC regular group data register
524 \param[in] none
525 \param[out] none
526 \retval the conversion value
527 */
adc_regular_data_read(void)528 uint16_t adc_regular_data_read(void)
529 {
530 return ((uint16_t)ADC_RDATA);
531 }
532
533 /*!
534 \brief read ADC inserted group data register
535 \param[in] inserted_channel: inserted channel select
536 only one parameter can be selected which is shown as below:
537 \arg ADC_INSERTED_CHANNEL_0: ADC inserted channel 0
538 \arg ADC_INSERTED_CHANNEL_1: ADC inserted channel 1
539 \arg ADC_INSERTED_CHANNEL_2: ADC inserted channel 2
540 \arg ADC_INSERTED_CHANNEL_3: ADC inserted channel 3
541 \param[out] none
542 \retval the conversion value
543 */
adc_inserted_data_read(uint8_t inserted_channel)544 uint16_t adc_inserted_data_read(uint8_t inserted_channel)
545 {
546 uint32_t idata;
547 /* read the data of the selected channel */
548 switch(inserted_channel){
549 case ADC_INSERTED_CHANNEL_0:
550 idata = ADC_IDATA0;
551 break;
552 case ADC_INSERTED_CHANNEL_1:
553 idata = ADC_IDATA1;
554 break;
555 case ADC_INSERTED_CHANNEL_2:
556 idata = ADC_IDATA2;
557 break;
558 case ADC_INSERTED_CHANNEL_3:
559 idata = ADC_IDATA3;
560 break;
561 default:
562 idata = 0U;
563 break;
564 }
565 return (uint16_t)idata;
566 }
567
568 /*!
569 \brief get the ADC flag bits
570 \param[in] flag: the adc flag bits
571 only one parameter can be selected which is shown as below:
572 \arg ADC_FLAG_WDE: analog watchdog event flag
573 \arg ADC_FLAG_EOC: end of group conversion flag
574 \arg ADC_FLAG_EOIC: end of inserted group conversion flag
575 \arg ADC_FLAG_STIC: start flag of inserted channel group
576 \arg ADC_FLAG_STRC: start flag of regular channel group
577 \param[out] none
578 \retval FlagStatus: SET or RESET
579 */
adc_flag_get(uint32_t flag)580 FlagStatus adc_flag_get(uint32_t flag)
581 {
582 FlagStatus reval = RESET;
583
584 if(ADC_STAT & flag){
585 reval = SET;
586 }
587 return reval;
588 }
589
590 /*!
591 \brief clear the ADC flag
592 \param[in] flag: the adc flag
593 one or more parameters can be selected which is shown as below:
594 \arg ADC_FLAG_WDE: analog watchdog event flag
595 \arg ADC_FLAG_EOC: end of group conversion flag
596 \arg ADC_FLAG_EOIC: end of inserted group conversion flag
597 \arg ADC_FLAG_STIC: start flag of inserted channel group
598 \arg ADC_FLAG_STRC: start flag of regular channel group
599 \param[out] none
600 \retval none
601 */
adc_flag_clear(uint32_t flag)602 void adc_flag_clear(uint32_t flag)
603 {
604 ADC_STAT &= ~((uint32_t)flag);
605 }
606
607 /*!
608 \brief get the ADC interrupt flag
609 \param[in] flag: the adc interrupt flag
610 only one parameter can be selected which is shown as below:
611 \arg ADC_INT_FLAG_WDE: analog watchdog interrupt flag
612 \arg ADC_INT_FLAG_EOC: end of group conversion interrupt flag
613 \arg ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt flag
614 \param[out] none
615 \retval FlagStatus: SET or RESET
616 */
adc_interrupt_flag_get(uint32_t flag)617 FlagStatus adc_interrupt_flag_get(uint32_t flag)
618 {
619 FlagStatus interrupt_flag = RESET;
620 uint32_t state;
621
622 /* check the interrupt bits */
623 switch(flag){
624 case ADC_INT_FLAG_WDE:
625 state = ADC_STAT & ADC_STAT_WDE;
626 if((ADC_CTL0 & ADC_CTL0_WDEIE) && state){
627 interrupt_flag = SET;
628 }
629 break;
630 case ADC_INT_FLAG_EOC:
631 state = ADC_STAT & ADC_STAT_EOC;
632 if((ADC_CTL0 & ADC_CTL0_EOCIE) && state){
633 interrupt_flag = SET;
634 }
635 break;
636 case ADC_INT_FLAG_EOIC:
637 state = ADC_STAT & ADC_STAT_EOIC;
638 if((ADC_CTL0 & ADC_CTL0_EOICIE) && state){
639 interrupt_flag = SET;
640 }
641 break;
642 default:
643 break;
644 }
645 return interrupt_flag;
646 }
647
648 /*!
649 \brief clear ADC interrupt flag
650 \param[in] flag: the adc interrupt flag
651 only one parameter can be selected which is shown as below:
652 \arg ADC_INT_FLAG_WDE: analog watchdog interrupt flag
653 \arg ADC_INT_FLAG_EOC: end of group conversion interrupt flag
654 \arg ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt flag
655 \param[out] none
656 \retval none
657 */
adc_interrupt_flag_clear(uint32_t flag)658 void adc_interrupt_flag_clear(uint32_t flag)
659 {
660 ADC_STAT &= ~((uint32_t)flag);
661 }
662
663 /*!
664 \brief enable ADC interrupt
665 \param[in] interrupt: the adc interrupt
666 one or more parameters can be selected which is shown as below:
667 \arg ADC_INT_WDE: analog watchdog interrupt
668 \arg ADC_INT_EOC: end of group conversion interrupt
669 \arg ADC_INT_EOIC: end of inserted group conversion interrupt
670 \param[out] none
671 \retval none
672 */
adc_interrupt_enable(uint32_t interrupt)673 void adc_interrupt_enable(uint32_t interrupt)
674 {
675 /* enable analog watchdog interrupt */
676 if(RESET != (interrupt & ADC_INT_WDE)){
677 ADC_CTL0 |= (uint32_t)ADC_CTL0_WDEIE;
678 }
679
680 /* enable end of group conversion interrupt */
681 if(RESET != (interrupt & ADC_INT_EOC)){
682 ADC_CTL0 |= (uint32_t)ADC_CTL0_EOCIE;
683 }
684
685 /* enable end of inserted group conversion interrupt */
686 if(RESET != (interrupt & ADC_INT_EOIC)){
687 ADC_CTL0 |= (uint32_t)ADC_CTL0_EOICIE;
688 }
689 }
690
691 /*!
692 \brief disable ADC interrupt
693 \param[in] interrupt: the adc interrupt flag
694 one or more parameters can be selected which is shown as below:
695 \arg ADC_INT_WDE: analog watchdog interrupt
696 \arg ADC_INT_EOC: end of group conversion interrupt
697 \arg ADC_INT_EOIC: end of inserted group conversion interrupt
698 \param[out] none
699 \retval none
700 */
adc_interrupt_disable(uint32_t interrupt)701 void adc_interrupt_disable(uint32_t interrupt)
702 {
703 /* disable analog watchdog interrupt */
704 if(RESET != (interrupt & ADC_INT_WDE)){
705 ADC_CTL0 &= ~(uint32_t)ADC_CTL0_WDEIE;
706 }
707
708 /* disable end of group conversion interrupt */
709 if(RESET != (interrupt & ADC_INT_EOC)){
710 ADC_CTL0 &= ~(uint32_t)ADC_CTL0_EOCIE;
711 }
712
713 /* disable end of inserted group conversion interrupt */
714 if(RESET != (interrupt & ADC_INT_EOIC)){
715 ADC_CTL0 &= ~(uint32_t)ADC_CTL0_EOICIE;
716 }
717 }
718
719 /*!
720 \brief configure ADC analog watchdog single channel
721 \param[in] channel: the selected ADC channel
722 only one parameter can be selected which is shown as below:
723 \arg ADC_CHANNEL_x(x=0..18): ADC Channelx
724 \param[out] none
725 \retval none
726 */
adc_watchdog_single_channel_enable(uint8_t channel)727 void adc_watchdog_single_channel_enable(uint8_t channel)
728 {
729 ADC_CTL0 &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC | ADC_CTL0_WDCHSEL);
730
731 ADC_CTL0 |= (uint32_t)channel;
732 ADC_CTL0 |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC);
733 }
734
735 /*!
736 \brief configure ADC analog watchdog group channel
737 \param[in] channel_group: the channel group use analog watchdog
738 only one parameter can be selected which is shown as below:
739 \arg ADC_REGULAR_CHANNEL: regular channel group
740 \arg ADC_INSERTED_CHANNEL: inserted channel group
741 \arg ADC_REGULAR_INSERTED_CHANNEL: both regular and inserted group
742 \param[out] none
743 \retval none
744 */
adc_watchdog_group_channel_enable(uint8_t channel_group)745 void adc_watchdog_group_channel_enable(uint8_t channel_group)
746 {
747 ADC_CTL0 &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC);
748
749 /* select the group */
750 switch(channel_group){
751 case ADC_REGULAR_CHANNEL:
752 ADC_CTL0 |= (uint32_t)ADC_CTL0_RWDEN;
753 break;
754 case ADC_INSERTED_CHANNEL:
755 ADC_CTL0 |= (uint32_t)ADC_CTL0_IWDEN;
756 break;
757 case ADC_REGULAR_INSERTED_CHANNEL:
758 ADC_CTL0 |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN);
759 break;
760 default:
761 break;
762 }
763 }
764
765 /*!
766 \brief disable ADC analog watchdog
767 \param[in] none
768 \param[out] none
769 \retval none
770 */
adc_watchdog_disable(void)771 void adc_watchdog_disable(void)
772 {
773 ADC_CTL0 &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC | ADC_CTL0_WDCHSEL);
774 }
775
776 /*!
777 \brief configure ADC analog watchdog threshold
778 \param[in] low_threshold: analog watchdog low threshold,0..4095
779 \param[in] high_threshold: analog watchdog high threshold,0..4095
780 \param[out] none
781 \retval none
782 */
adc_watchdog_threshold_config(uint16_t low_threshold,uint16_t high_threshold)783 void adc_watchdog_threshold_config(uint16_t low_threshold, uint16_t high_threshold)
784 {
785 ADC_WDLT = (uint32_t)WDLT_WDLT(low_threshold);
786 ADC_WDHT = (uint32_t)WDHT_WDHT(high_threshold);
787 }
788
789 /*!
790 \brief configure ADC resolution
791 \param[in] resolution: ADC resolution
792 only one parameter can be selected which is shown as below:
793 \arg ADC_RESOLUTION_12B: 12-bit ADC resolution
794 \arg ADC_RESOLUTION_10B: 10-bit ADC resolution
795 \arg ADC_RESOLUTION_8B: 8-bit ADC resolution
796 \arg ADC_RESOLUTION_6B: 6-bit ADC resolution
797 \param[out] none
798 \retval none
799 */
adc_resolution_config(uint32_t resolution)800 void adc_resolution_config(uint32_t resolution)
801 {
802 ADC_CTL0 &= ~((uint32_t)ADC_CTL0_DRES);
803 ADC_CTL0 |= (uint32_t)resolution;
804 }
805
806 /*!
807 \brief configure ADC oversample mode
808 \param[in] mode: ADC oversampling mode
809 only one parameter can be selected which is shown as below:
810 \arg ADC_OVERSAMPLING_ALL_CONVERT: all oversampled conversions for a channel are done consecutively after a trigger
811 \arg ADC_OVERSAMPLING_ONE_CONVERT: each oversampled conversion for a channel needs a trigger
812 \param[in] shift: ADC oversampling shift
813 only one parameter can be selected which is shown as below:
814 \arg ADC_OVERSAMPLING_SHIFT_NONE: no oversampling shift
815 \arg ADC_OVERSAMPLING_SHIFT_1B: 1-bit oversampling shift
816 \arg ADC_OVERSAMPLING_SHIFT_2B: 2-bit oversampling shift
817 \arg ADC_OVERSAMPLING_SHIFT_3B: 3-bit oversampling shift
818 \arg ADC_OVERSAMPLING_SHIFT_4B: 3-bit oversampling shift
819 \arg ADC_OVERSAMPLING_SHIFT_5B: 5-bit oversampling shift
820 \arg ADC_OVERSAMPLING_SHIFT_6B: 6-bit oversampling shift
821 \arg ADC_OVERSAMPLING_SHIFT_7B: 7-bit oversampling shift
822 \arg ADC_OVERSAMPLING_SHIFT_8B: 8-bit oversampling shift
823 \param[in] ratio: ADC oversampling ratio
824 only one parameter can be selected which is shown as below:
825 \arg ADC_OVERSAMPLING_RATIO_MUL2: oversampling ratio multiple 2
826 \arg ADC_OVERSAMPLING_RATIO_MUL4: oversampling ratio multiple 4
827 \arg ADC_OVERSAMPLING_RATIO_MUL8: oversampling ratio multiple 8
828 \arg ADC_OVERSAMPLING_RATIO_MUL16: oversampling ratio multiple 16
829 \arg ADC_OVERSAMPLING_RATIO_MUL32: oversampling ratio multiple 32
830 \arg ADC_OVERSAMPLING_RATIO_MUL64: oversampling ratio multiple 64
831 \arg ADC_OVERSAMPLING_RATIO_MUL128: oversampling ratio multiple 128
832 \arg ADC_OVERSAMPLING_RATIO_MUL256: oversampling ratio multiple 256
833 \param[out] none
834 \retval none
835 */
adc_oversample_mode_config(uint8_t mode,uint16_t shift,uint8_t ratio)836 void adc_oversample_mode_config(uint8_t mode, uint16_t shift, uint8_t ratio)
837 {
838 /* configure ADC oversampling mode */
839 if(ADC_OVERSAMPLING_ONE_CONVERT == mode){
840 ADC_OVSAMPCTL |= (uint32_t)ADC_OVSAMPCTL_TOVS;
841 }else{
842 ADC_OVSAMPCTL &= ~((uint32_t)ADC_OVSAMPCTL_TOVS);
843 }
844
845 /* configure the shift and ratio */
846 ADC_OVSAMPCTL &= ~((uint32_t)(ADC_OVSAMPCTL_OVSR | ADC_OVSAMPCTL_OVSS));
847 ADC_OVSAMPCTL |= ((uint32_t)shift | (uint32_t)ratio);
848 }
849
850 /*!
851 \brief enable ADC oversample mode
852 \param[in] none
853 \param[out] none
854 \retval none
855 */
adc_oversample_mode_enable(void)856 void adc_oversample_mode_enable(void)
857 {
858 ADC_OVSAMPCTL |= ADC_OVSAMPCTL_OVSEN;
859 }
860
861 /*!
862 \brief disable ADC oversample mode
863 \param[in] none
864 \param[out] none
865 \retval none
866 */
adc_oversample_mode_disable(void)867 void adc_oversample_mode_disable(void)
868 {
869 ADC_OVSAMPCTL &= ~((uint32_t)ADC_OVSAMPCTL_OVSEN);
870 }
871