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