1 /*!
2     \file    gd32f4xx_adc.c
3     \brief   ADC driver
4 
5     \version 2016-08-15, V1.0.0, firmware for GD32F4xx
6     \version 2018-12-12, V2.0.0, firmware for GD32F4xx
7     \version 2020-09-30, V2.1.0, firmware for GD32F4xx
8     \version 2022-03-09, V3.0.0, firmware for GD32F4xx
9 */
10 
11 /*
12     Copyright (c) 2022, GigaDevice Semiconductor Inc.
13 
14     Redistribution and use in source and binary forms, with or without modification,
15 are permitted provided that the following conditions are met:
16 
17     1. Redistributions of source code must retain the above copyright notice, this
18        list of conditions and the following disclaimer.
19     2. Redistributions in binary form must reproduce the above copyright notice,
20        this list of conditions and the following disclaimer in the documentation
21        and/or other materials provided with the distribution.
22     3. Neither the name of the copyright holder nor the names of its contributors
23        may be used to endorse or promote products derived from this software without
24        specific prior written permission.
25 
26     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
30 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
35 OF SUCH DAMAGE.
36 */
37 
38 #include "gd32f4xx_adc.h"
39 
40 #define REGULAR_TRIGGER_MODE                        ((uint32_t)28U)
41 #define INSERTED_TRIGGER_MODE                       ((uint32_t)20U)
42 /* discontinuous mode macro*/
43 #define  ADC_CHANNEL_LENGTH_SUBTRACT_ONE            ((uint8_t)1U)
44 
45 /* ADC regular channel macro */
46 #define  ADC_REGULAR_CHANNEL_RANK_SIX               ((uint8_t)6U)
47 #define  ADC_REGULAR_CHANNEL_RANK_TWELVE            ((uint8_t)12U)
48 #define  ADC_REGULAR_CHANNEL_RANK_SIXTEEN           ((uint8_t)16U)
49 #define  ADC_REGULAR_CHANNEL_RANK_LENGTH            ((uint8_t)5U)
50 
51 /* ADC sampling time macro */
52 #define  ADC_CHANNEL_SAMPLE_TEN                     ((uint8_t)10U)
53 #define  ADC_CHANNEL_SAMPLE_EIGHTEEN                ((uint8_t)18U)
54 #define  ADC_CHANNEL_SAMPLE_LENGTH                  ((uint8_t)3U)
55 
56 /* ADC inserted channel macro */
57 #define  ADC_INSERTED_CHANNEL_RANK_LENGTH           ((uint8_t)5U)
58 #define  ADC_INSERTED_CHANNEL_SHIFT_LENGTH          ((uint8_t)15U)
59 
60 /* ADC inserted channel offset macro */
61 #define  ADC_OFFSET_LENGTH                          ((uint8_t)3U)
62 #define  ADC_OFFSET_SHIFT_LENGTH                    ((uint8_t)4U)
63 
64 /*!
65     \brief    reset ADC
66     \param[in]  none
67     \param[out] none
68     \retval     none
69 */
adc_deinit(void)70 void adc_deinit(void)
71 {
72     rcu_periph_reset_enable(RCU_ADCRST);
73     rcu_periph_reset_disable(RCU_ADCRST);
74 }
75 
76 /*!
77     \brief        configure the ADC clock for all the ADCs
78     \param[in]    prescaler: configure ADCs prescaler ratio
79                   only one parameter can be selected which is shown as below:
80       \arg        ADC_ADCCK_PCLK2_DIV2: PCLK2 div2
81       \arg        ADC_ADCCK_PCLK2_DIV4: PCLK2 div4
82       \arg        ADC_ADCCK_PCLK2_DIV6: PCLK2 div6
83       \arg        ADC_ADCCK_PCLK2_DIV8: PCLK2 div8
84       \arg        ADC_ADCCK_HCLK_DIV5: HCLK div5
85       \arg        ADC_ADCCK_HCLK_DIV6: HCLK div6
86       \arg        ADC_ADCCK_HCLK_DIV10: HCLK div10
87       \arg        ADC_ADCCK_HCLK_DIV20: HCLK div20
88     \param[out]   none
89     \retval       none
90 */
adc_clock_config(uint32_t prescaler)91 void adc_clock_config(uint32_t prescaler)
92 {
93     ADC_SYNCCTL &= ~((uint32_t)ADC_SYNCCTL_ADCCK);
94     ADC_SYNCCTL |= (uint32_t) prescaler;
95 }
96 
97 /*!
98     \brief        enable or disable ADC special function
99     \param[in]    adc_periph: ADCx,x=0,1,2
100     \param[in]    function: the function to config
101                   only one parameter can be selected which is shown as below:
102     \arg          ADC_SCAN_MODE: scan mode select
103     \arg          ADC_INSERTED_CHANNEL_AUTO: inserted channel group convert automatically
104     \arg          ADC_CONTINUOUS_MODE: continuous mode select
105     \param[in]    newvalue: ENABLE or DISABLE
106     \param[out]   none
107     \retval       none
108 */
adc_special_function_config(uint32_t adc_periph,uint32_t function,ControlStatus newvalue)109 void adc_special_function_config(uint32_t adc_periph, uint32_t function, ControlStatus newvalue)
110 {
111     if(newvalue) {
112         if(0U != (function & ADC_SCAN_MODE)) {
113             /* enable scan mode */
114             ADC_CTL0(adc_periph) |= ADC_SCAN_MODE;
115         }
116         if(0U != (function & ADC_INSERTED_CHANNEL_AUTO)) {
117             /* enable inserted channel group convert automatically */
118             ADC_CTL0(adc_periph) |= ADC_INSERTED_CHANNEL_AUTO;
119         }
120         if(0U != (function & ADC_CONTINUOUS_MODE)) {
121             /* enable continuous mode */
122             ADC_CTL1(adc_periph) |= ADC_CONTINUOUS_MODE;
123         }
124     } else {
125         if(0U != (function & ADC_SCAN_MODE)) {
126             /* disable scan mode */
127             ADC_CTL0(adc_periph) &= ~ADC_SCAN_MODE;
128         }
129         if(0U != (function & ADC_INSERTED_CHANNEL_AUTO)) {
130             /* disable inserted channel group convert automatically */
131             ADC_CTL0(adc_periph) &= ~ADC_INSERTED_CHANNEL_AUTO;
132         }
133         if(0U != (function & ADC_CONTINUOUS_MODE)) {
134             /* disable continuous mode */
135             ADC_CTL1(adc_periph) &= ~ADC_CONTINUOUS_MODE;
136         }
137     }
138 }
139 
140 /*!
141     \brief        configure ADC data alignment
142     \param[in]    adc_periph: ADCx,x=0,1,2
143     \param[in]    data_alignment: data alignment select
144                   only one parameter can be selected which is shown as below:
145     \arg          ADC_DATAALIGN_RIGHT: LSB alignment
146     \arg          ADC_DATAALIGN_LEFT: MSB alignment
147     \param[out]   none
148     \retval       none
149 */
adc_data_alignment_config(uint32_t adc_periph,uint32_t data_alignment)150 void adc_data_alignment_config(uint32_t adc_periph, uint32_t data_alignment)
151 {
152     if(ADC_DATAALIGN_RIGHT != data_alignment) {
153         /* MSB alignment */
154         ADC_CTL1(adc_periph) |= ADC_CTL1_DAL;
155     } else {
156         /* LSB alignment */
157         ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DAL);
158     }
159 }
160 
161 /*!
162     \brief        enable ADC interface
163     \param[in]    adc_periph: ADCx,x=0,1,2
164     \param[out]   none
165     \retval       none
166 */
adc_enable(uint32_t adc_periph)167 void adc_enable(uint32_t adc_periph)
168 {
169     if(RESET == (ADC_CTL1(adc_periph) & ADC_CTL1_ADCON)) {
170         /* enable ADC */
171         ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_ADCON;
172     }
173 }
174 
175 /*!
176     \brief        disable ADC interface
177     \param[in]    adc_periph: ADCx,x=0,1,2
178     \param[out]   none
179     \retval       none
180 */
adc_disable(uint32_t adc_periph)181 void adc_disable(uint32_t adc_periph)
182 {
183     /* disable ADC */
184     ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ADCON);
185 }
186 
187 /*!
188     \brief        ADC calibration and reset calibration
189     \param[in]    adc_periph: ADCx,x=0,1,2
190     \param[out]   none
191     \retval       none
192 */
adc_calibration_enable(uint32_t adc_periph)193 void adc_calibration_enable(uint32_t adc_periph)
194 {
195     /* reset the selected ADC calibration registers */
196     ADC_CTL1(adc_periph) |= (uint32_t) ADC_CTL1_RSTCLB;
197     /* check the RSTCLB bit state */
198     while(RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_RSTCLB)) {
199     }
200     /* enable ADC calibration process */
201     ADC_CTL1(adc_periph) |= ADC_CTL1_CLB;
202     /* check the CLB bit state */
203     while(RESET != (ADC_CTL1(adc_periph) & ADC_CTL1_CLB)) {
204     }
205 }
206 
207 /*!
208     \brief        configure temperature sensor and internal reference voltage channel or VBAT channel function
209     \param[in]    function: temperature sensor and internal reference voltage channel or VBAT channel
210                   only one parameter can be selected which is shown as below:
211     \arg          ADC_VBAT_CHANNEL_SWITCH: channel 18 (1/4 voltate of external battery) switch of ADC0
212     \arg          ADC_TEMP_VREF_CHANNEL_SWITCH: channel 16 (temperature sensor) and 17 (internal reference voltage) switch of ADC0
213     \param[in]    newvalue: ENABLE or DISABLE
214     \param[out]   none
215     \retval       none
216 */
adc_channel_16_to_18(uint32_t function,ControlStatus newvalue)217 void adc_channel_16_to_18(uint32_t function, ControlStatus newvalue)
218 {
219     if(newvalue) {
220         if(RESET != (function & ADC_VBAT_CHANNEL_SWITCH)) {
221             /* enable ADC0 Vbat channel */
222             ADC_SYNCCTL |= ADC_VBAT_CHANNEL_SWITCH;
223         }
224         if(RESET != (function & ADC_TEMP_VREF_CHANNEL_SWITCH)) {
225             /* enable ADC0 Vref and Temperature channel */
226             ADC_SYNCCTL |= ADC_TEMP_VREF_CHANNEL_SWITCH;
227         }
228     } else {
229         if(RESET != (function & ADC_VBAT_CHANNEL_SWITCH)) {
230             /* disable ADC0 Vbat channel  */
231             ADC_SYNCCTL &= ~ADC_VBAT_CHANNEL_SWITCH;
232         }
233         if(RESET != (function & ADC_TEMP_VREF_CHANNEL_SWITCH)) {
234             /* disable ADC0 Vref and Temperature channel */
235             ADC_SYNCCTL &= ~ADC_TEMP_VREF_CHANNEL_SWITCH;
236         }
237     }
238 }
239 
240 /*!
241     \brief        configure ADC resolution
242     \param[in]    adc_periph: ADCx,x=0,1,2
243     \param[in]    resolution: ADC resolution
244                   only one parameter can be selected which is shown as below:
245     \arg          ADC_RESOLUTION_12B: 12-bit ADC resolution
246     \arg          ADC_RESOLUTION_10B: 10-bit ADC resolution
247     \arg          ADC_RESOLUTION_8B: 8-bit ADC resolution
248     \arg          ADC_RESOLUTION_6B: 6-bit ADC resolution
249     \param[out]   none
250     \retval       none
251 */
adc_resolution_config(uint32_t adc_periph,uint32_t resolution)252 void adc_resolution_config(uint32_t adc_periph, uint32_t resolution)
253 {
254     ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_DRES);
255     ADC_CTL0(adc_periph) |= (uint32_t)resolution;
256 }
257 
258 /*!
259     \brief        configure ADC oversample mode
260     \param[in]    adc_periph: ADCx,x=0,1,2
261     \param[in]    mode: ADC oversampling mode
262                   only one parameter can be selected which is shown as below:
263     \arg          ADC_OVERSAMPLING_ALL_CONVERT: all oversampled conversions for a channel are done consecutively after a trigger
264     \arg          ADC_OVERSAMPLING_ONE_CONVERT: each oversampled conversion for a channel needs a trigger
265     \param[in]    shift: ADC oversampling shift
266                   only one parameter can be selected which is shown as below:
267     \arg          ADC_OVERSAMPLING_SHIFT_NONE: no oversampling shift
268     \arg          ADC_OVERSAMPLING_SHIFT_1B: 1-bit oversampling shift
269     \arg          ADC_OVERSAMPLING_SHIFT_2B: 2-bit oversampling shift
270     \arg          ADC_OVERSAMPLING_SHIFT_3B: 3-bit oversampling shift
271     \arg          ADC_OVERSAMPLING_SHIFT_4B: 3-bit oversampling shift
272     \arg          ADC_OVERSAMPLING_SHIFT_5B: 5-bit oversampling shift
273     \arg          ADC_OVERSAMPLING_SHIFT_6B: 6-bit oversampling shift
274     \arg          ADC_OVERSAMPLING_SHIFT_7B: 7-bit oversampling shift
275     \arg          ADC_OVERSAMPLING_SHIFT_8B: 8-bit oversampling shift
276     \param[in]    ratio: ADC oversampling ratio
277                   only one parameter can be selected which is shown as below:
278     \arg          ADC_OVERSAMPLING_RATIO_MUL2: oversampling ratio multiple 2
279     \arg          ADC_OVERSAMPLING_RATIO_MUL4: oversampling ratio multiple 4
280     \arg          ADC_OVERSAMPLING_RATIO_MUL8: oversampling ratio multiple 8
281     \arg          ADC_OVERSAMPLING_RATIO_MUL16: oversampling ratio multiple 16
282     \arg          ADC_OVERSAMPLING_RATIO_MUL32: oversampling ratio multiple 32
283     \arg          ADC_OVERSAMPLING_RATIO_MUL64: oversampling ratio multiple 64
284     \arg          ADC_OVERSAMPLING_RATIO_MUL128: oversampling ratio multiple 128
285     \arg          ADC_OVERSAMPLING_RATIO_MUL256: oversampling ratio multiple 256
286     \param[out]   none
287     \retval       none
288 */
adc_oversample_mode_config(uint32_t adc_periph,uint32_t mode,uint16_t shift,uint8_t ratio)289 void adc_oversample_mode_config(uint32_t adc_periph, uint32_t mode, uint16_t shift, uint8_t ratio)
290 {
291     if(ADC_OVERSAMPLING_ONE_CONVERT == mode) {
292         ADC_OVSAMPCTL(adc_periph) |= (uint32_t)ADC_OVSAMPCTL_TOVS;
293     } else {
294         ADC_OVSAMPCTL(adc_periph) &= ~((uint32_t)ADC_OVSAMPCTL_TOVS);
295     }
296     /* config the shift and ratio */
297     ADC_OVSAMPCTL(adc_periph) &= ~((uint32_t)(ADC_OVSAMPCTL_OVSR | ADC_OVSAMPCTL_OVSS));
298     ADC_OVSAMPCTL(adc_periph) |= ((uint32_t)shift | (uint32_t)ratio);
299 }
300 
301 /*!
302     \brief        enable ADC oversample mode
303     \param[in]    adc_periph: ADCx,x=0,1,2
304     \param[out]   none
305     \retval       none
306 */
adc_oversample_mode_enable(uint32_t adc_periph)307 void adc_oversample_mode_enable(uint32_t adc_periph)
308 {
309     ADC_OVSAMPCTL(adc_periph) |= ADC_OVSAMPCTL_OVSEN;
310 }
311 
312 /*!
313     \brief        disable ADC oversample mode
314     \param[in]    adc_periph: ADCx,x=0,1,2
315     \param[out]   none
316     \retval       none
317 */
adc_oversample_mode_disable(uint32_t adc_periph)318 void adc_oversample_mode_disable(uint32_t adc_periph)
319 {
320     ADC_OVSAMPCTL(adc_periph) &= ~((uint32_t)ADC_OVSAMPCTL_OVSEN);
321 }
322 
323 /*!
324     \brief        enable DMA request
325     \param[in]    adc_periph: ADCx,x=0,1,2
326     \param[out]   none
327     \retval       none
328 */
adc_dma_mode_enable(uint32_t adc_periph)329 void adc_dma_mode_enable(uint32_t adc_periph)
330 {
331     /* enable DMA request */
332     ADC_CTL1(adc_periph) |= (uint32_t)(ADC_CTL1_DMA);
333 }
334 
335 /*!
336     \brief      disable DMA request
337     \param[in]  adc_periph: ADCx,x=0,1,2
338     \param[out] none
339     \retval     none
340 */
adc_dma_mode_disable(uint32_t adc_periph)341 void adc_dma_mode_disable(uint32_t adc_periph)
342 {
343     /* disable DMA request */
344     ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DMA);
345 }
346 
347 /*!
348     \brief    when DMA=1, the DMA engine issues a request at end of each regular conversion
349     \param[in]  adc_periph: ADCx,x=0,1,2
350     \param[out] none
351     \retval     none
352 */
adc_dma_request_after_last_enable(uint32_t adc_periph)353 void adc_dma_request_after_last_enable(uint32_t adc_periph)
354 {
355     ADC_CTL1(adc_periph) |= (uint32_t)(ADC_CTL1_DDM);
356 }
357 
358 /*!
359     \brief    the DMA engine is disabled after the end of transfer signal from DMA controller is detected
360     \param[in]  adc_periph: ADCx,x=0,1,2
361     \param[out] none
362     \retval     none
363 */
adc_dma_request_after_last_disable(uint32_t adc_periph)364 void adc_dma_request_after_last_disable(uint32_t adc_periph)
365 {
366     ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_DDM);
367 }
368 
369 /*!
370     \brief        configure ADC discontinuous mode
371     \param[in]    adc_periph: ADCx,x=0,1,2
372     \param[in]    adc_channel_group: select the channel group
373                   only one parameter can be selected which is shown as below:
374     \arg          ADC_REGULAR_CHANNEL: regular channel group
375     \arg          ADC_INSERTED_CHANNEL: inserted channel group
376     \arg          ADC_CHANNEL_DISCON_DISABLE: disable discontinuous mode of regular & inserted channel
377     \param[in]    length: number of conversions in discontinuous mode,the number can be 1..8
378                   for regular channel ,the number has no effect for inserted channel
379     \param[out]   none
380     \retval       none
381 */
adc_discontinuous_mode_config(uint32_t adc_periph,uint8_t adc_channel_group,uint8_t length)382 void adc_discontinuous_mode_config(uint32_t adc_periph, uint8_t adc_channel_group, uint8_t length)
383 {
384     /* disable discontinuous mode of regular & inserted channel */
385     ADC_CTL0(adc_periph) &= ~((uint32_t)(ADC_CTL0_DISRC | ADC_CTL0_DISIC));
386     switch(adc_channel_group) {
387     case ADC_REGULAR_CHANNEL:
388         /* config the number of conversions in discontinuous mode  */
389         ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_DISNUM);
390         if((length <= 8U) && (length >= 1U)) {
391             ADC_CTL0(adc_periph) |= CTL0_DISNUM(((uint32_t)length - ADC_CHANNEL_LENGTH_SUBTRACT_ONE));
392         }
393         /* enable regular channel group discontinuous mode */
394         ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISRC;
395         break;
396     case ADC_INSERTED_CHANNEL:
397         /* enable inserted channel group discontinuous mode */
398         ADC_CTL0(adc_periph) |= (uint32_t)ADC_CTL0_DISIC;
399         break;
400     case ADC_CHANNEL_DISCON_DISABLE:
401     /* disable discontinuous mode of regular & inserted channel */
402     default:
403         break;
404     }
405 }
406 
407 /*!
408     \brief        configure the length of regular channel group or inserted channel group
409     \param[in]    adc_periph: ADCx,x=0,1,2
410     \param[in]    adc_channel_group: select the channel group
411                   only one parameter can be selected which is shown as below:
412     \arg          ADC_REGULAR_CHANNEL: regular channel group
413     \arg          ADC_INSERTED_CHANNEL: inserted channel group
414     \param[in]    length: the length of the channel
415                   regular channel 1-16
416                   inserted channel 1-4
417     \param[out]   none
418     \retval       none
419 */
adc_channel_length_config(uint32_t adc_periph,uint8_t adc_channel_group,uint32_t length)420 void adc_channel_length_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t length)
421 {
422     switch(adc_channel_group) {
423     case ADC_REGULAR_CHANNEL:
424         if((length >= 1U) && (length <= 16U)) {
425             ADC_RSQ0(adc_periph) &= ~((uint32_t)ADC_RSQ0_RL);
426             ADC_RSQ0(adc_periph) |= RSQ0_RL((uint32_t)(length - ADC_CHANNEL_LENGTH_SUBTRACT_ONE));
427         }
428         break;
429     case ADC_INSERTED_CHANNEL:
430         if((length >= 1U) && (length <= 4U)) {
431             ADC_ISQ(adc_periph) &= ~((uint32_t)ADC_ISQ_IL);
432             ADC_ISQ(adc_periph) |= ISQ_IL((uint32_t)(length - ADC_CHANNEL_LENGTH_SUBTRACT_ONE));
433         }
434         break;
435     default:
436         break;
437     }
438 }
439 
440 /*!
441     \brief        configure ADC regular channel
442     \param[in]    adc_periph: ADCx,x=0,1,2
443     \param[in]    rank: the regular group sequencer rank,this parameter must be between 0 to 15
444     \param[in]    adc_channel: the selected ADC channel
445                   only one parameter can be selected which is shown as below:
446     \arg          ADC_CHANNEL_x(x=0..18): ADC Channelx
447     \param[in]    sample_time: the sample time value
448                   only one parameter can be selected which is shown as below:
449     \arg          ADC_SAMPLETIME_3: 3 cycles
450     \arg          ADC_SAMPLETIME_15: 15 cycles
451     \arg          ADC_SAMPLETIME_28: 28 cycles
452     \arg          ADC_SAMPLETIME_56: 56 cycles
453     \arg          ADC_SAMPLETIME_84: 84 cycles
454     \arg          ADC_SAMPLETIME_112: 112 cycles
455     \arg          ADC_SAMPLETIME_144: 144 cycles
456     \arg          ADC_SAMPLETIME_480: 480 cycles
457     \param[out]   none
458     \retval       none
459 */
adc_regular_channel_config(uint32_t adc_periph,uint8_t rank,uint8_t adc_channel,uint32_t sample_time)460 void adc_regular_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time)
461 {
462     uint32_t rsq, sampt;
463 
464     /* ADC regular sequence config */
465     if(rank < ADC_REGULAR_CHANNEL_RANK_SIX) {
466         /* the regular group sequence rank is smaller than six */
467         rsq = ADC_RSQ2(adc_periph);
468         rsq &=  ~((uint32_t)(ADC_RSQX_RSQN << (ADC_REGULAR_CHANNEL_RANK_LENGTH * rank)));
469         /* the channel number is written to these bits to select a channel as the nth conversion in the regular channel group */
470         rsq |= ((uint32_t)adc_channel << (ADC_REGULAR_CHANNEL_RANK_LENGTH * rank));
471         ADC_RSQ2(adc_periph) = rsq;
472     } else if(rank < ADC_REGULAR_CHANNEL_RANK_TWELVE) {
473         /* the regular group sequence rank is smaller than twelve */
474         rsq = ADC_RSQ1(adc_periph);
475         rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_REGULAR_CHANNEL_RANK_LENGTH * (rank - ADC_REGULAR_CHANNEL_RANK_SIX))));
476         /* the channel number is written to these bits to select a channel as the nth conversion in the regular channel group */
477         rsq |= ((uint32_t)adc_channel << (ADC_REGULAR_CHANNEL_RANK_LENGTH * (rank - ADC_REGULAR_CHANNEL_RANK_SIX)));
478         ADC_RSQ1(adc_periph) = rsq;
479     } else if(rank < ADC_REGULAR_CHANNEL_RANK_SIXTEEN) {
480         /* the regular group sequence rank is smaller than sixteen */
481         rsq = ADC_RSQ0(adc_periph);
482         rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (ADC_REGULAR_CHANNEL_RANK_LENGTH * (rank - ADC_REGULAR_CHANNEL_RANK_TWELVE))));
483         /* the channel number is written to these bits to select a channel as the nth conversion in the regular channel group */
484         rsq |= ((uint32_t)adc_channel << (ADC_REGULAR_CHANNEL_RANK_LENGTH * (rank - ADC_REGULAR_CHANNEL_RANK_TWELVE)));
485         ADC_RSQ0(adc_periph) = rsq;
486     } else {
487     }
488 
489     /* ADC sampling time config */
490     if(adc_channel < ADC_CHANNEL_SAMPLE_TEN) {
491         /* the regular group sequence rank is smaller than ten */
492         sampt = ADC_SAMPT1(adc_periph);
493         sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel)));
494         /* channel sample time set*/
495         sampt |= (uint32_t)(sample_time << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel));
496         ADC_SAMPT1(adc_periph) = sampt;
497     } else if(adc_channel <= ADC_CHANNEL_SAMPLE_EIGHTEEN) {
498         /* the regular group sequence rank is smaller than eighteen */
499         sampt = ADC_SAMPT0(adc_periph);
500         sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN))));
501         /* channel sample time set*/
502         sampt |= (uint32_t)(sample_time << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN)));
503         ADC_SAMPT0(adc_periph) = sampt;
504     } else {
505     }
506 }
507 
508 /*!
509     \brief    configure ADC inserted channel
510     \param[in]  adc_periph: ADCx,x=0,1,2
511     \param[in]  rank: the inserted group sequencer rank,this parameter must be between 0 to 3
512     \param[in]  adc_channel: the selected ADC channel
513                 only one parameter can be selected which is shown as below:
514     \arg        ADC_CHANNEL_x(x=0..18): ADC Channelx
515     \param[in]  sample_time: The sample time value
516                 only one parameter can be selected which is shown as below:
517     \arg        ADC_SAMPLETIME_3: 3 cycles
518     \arg        ADC_SAMPLETIME_15: 15 cycles
519     \arg        ADC_SAMPLETIME_28: 28 cycles
520     \arg        ADC_SAMPLETIME_56: 56 cycles
521     \arg        ADC_SAMPLETIME_84: 84 cycles
522     \arg        ADC_SAMPLETIME_112: 112 cycles
523     \arg        ADC_SAMPLETIME_144: 144 cycles
524     \arg        ADC_SAMPLETIME_480: 480 cycles
525     \param[out] none
526     \retval     none
527 */
adc_inserted_channel_config(uint32_t adc_periph,uint8_t rank,uint8_t adc_channel,uint32_t sample_time)528 void adc_inserted_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t adc_channel, uint32_t sample_time)
529 {
530     uint8_t inserted_length;
531     uint32_t isq, sampt;
532 
533     /* get inserted channel group length */
534     inserted_length = (uint8_t)GET_BITS(ADC_ISQ(adc_periph), 20U, 21U);
535     /* the channel number is written to these bits to select a channel as the nth conversion in the inserted channel group */
536     if(rank < 4U) {
537         isq = ADC_ISQ(adc_periph);
538         isq &= ~((uint32_t)(ADC_ISQ_ISQN << (ADC_INSERTED_CHANNEL_SHIFT_LENGTH - (inserted_length - rank) * ADC_INSERTED_CHANNEL_RANK_LENGTH)));
539         isq |= ((uint32_t)adc_channel << (ADC_INSERTED_CHANNEL_SHIFT_LENGTH - (inserted_length - rank) * ADC_INSERTED_CHANNEL_RANK_LENGTH));
540         ADC_ISQ(adc_periph) = isq;
541     }
542 
543     /* ADC sampling time config */
544     if(adc_channel < ADC_CHANNEL_SAMPLE_TEN) {
545         /* the inserted group sequence rank is smaller than ten */
546         sampt = ADC_SAMPT1(adc_periph);
547         sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel)));
548         /* channel sample time set*/
549         sampt |= (uint32_t) sample_time << (ADC_CHANNEL_SAMPLE_LENGTH * adc_channel);
550         ADC_SAMPT1(adc_periph) = sampt;
551     } else if(adc_channel <= ADC_CHANNEL_SAMPLE_EIGHTEEN) {
552         /* the inserted group sequence rank is smaller than eighteen */
553         sampt = ADC_SAMPT0(adc_periph);
554         sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN))));
555         /* channel sample time set*/
556         sampt |= ((uint32_t)sample_time << (ADC_CHANNEL_SAMPLE_LENGTH * (adc_channel - ADC_CHANNEL_SAMPLE_TEN)));
557         ADC_SAMPT0(adc_periph) = sampt;
558     } else {
559     }
560 }
561 
562 /*!
563     \brief      configure ADC inserted channel offset
564     \param[in]  adc_periph: ADCx,x=0,1,2
565     \param[in]  inserted_channel : insert channel select
566                 only one parameter can be selected which is shown as below:
567     \arg        ADC_INSERTED_CHANNEL_0: inserted channel0
568     \arg        ADC_INSERTED_CHANNEL_1: inserted channel1
569     \arg        ADC_INSERTED_CHANNEL_2: inserted channel2
570     \arg        ADC_INSERTED_CHANNEL_3: inserted channel3
571     \param[in]  offset : the offset data
572     \param[out] none
573     \retval     none
574 */
adc_inserted_channel_offset_config(uint32_t adc_periph,uint8_t inserted_channel,uint16_t offset)575 void adc_inserted_channel_offset_config(uint32_t adc_periph, uint8_t inserted_channel, uint16_t offset)
576 {
577     uint8_t inserted_length;
578     uint32_t num = 0U;
579 
580     inserted_length = (uint8_t)GET_BITS(ADC_ISQ(adc_periph), 20U, 21U);
581     num = ((uint32_t)ADC_OFFSET_LENGTH - ((uint32_t)inserted_length - (uint32_t)inserted_channel));
582 
583     if(num <= ADC_OFFSET_LENGTH) {
584         /* calculate the offset of the register */
585         num = num * ADC_OFFSET_SHIFT_LENGTH;
586         /* config the offset of the selected channels */
587         REG32((adc_periph) + 0x14U + num) = IOFFX_IOFF((uint32_t)offset);
588     }
589 }
590 
591 /*!
592     \brief      configure ADC external trigger source
593     \param[in]  adc_periph: ADCx,x=0,1,2
594     \param[in]  adc_channel_group: select the channel group
595                 only one parameter can be selected which is shown as below:
596     \arg        ADC_REGULAR_CHANNEL: regular channel group
597     \arg        ADC_INSERTED_CHANNEL: inserted channel group
598     \param[in]  external_trigger_source: regular or inserted group trigger source
599                 for regular channel:
600                 only one parameter can be selected which is shown as below:
601     \arg        ADC_EXTTRIG_REGULAR_T0_CH0: external trigger timer 0 CC0 event select for regular channel
602     \arg        ADC_EXTTRIG_REGULAR_T0_CH1: external trigger timer 0 CC1 event select for regular channel
603     \arg        ADC_EXTTRIG_REGULAR_T0_CH2: external trigger timer 0 CC2 event select for regular channel
604     \arg        ADC_EXTTRIG_REGULAR_T1_CH1: external trigger timer 1 CC1 event select for regular channel
605     \arg        ADC_EXTTRIG_REGULAR_T1_CH2: external trigger timer 1 CC2 event select for regular channel
606     \arg        ADC_EXTTRIG_REGULAR_T1_CH3: external trigger timer 1 CC3 event select for regular channel
607     \arg        ADC_EXTTRIG_REGULAR_T1_TRGO: external trigger timer 1 TRGO event select for regular channel
608     \arg        ADC_EXTTRIG_REGULAR_T2_CH0 : external trigger timer 2 CC0 event select for regular channel
609     \arg        ADC_EXTTRIG_REGULAR_T2_TRGO : external trigger timer 2 TRGO event select for regular channel
610     \arg        ADC_EXTTRIG_REGULAR_T3_CH3: external trigger timer 3 CC3 event select for regular channel
611     \arg        ADC_EXTTRIG_REGULAR_T4_CH0: external trigger timer 4 CC0 event select for regular channel
612     \arg        ADC_EXTTRIG_REGULAR_T4_CH1: external trigger timer 4 CC1 event select for regular channel
613     \arg        ADC_EXTTRIG_REGULAR_T4_CH2: external trigger timer 4 CC2 event select for regular channel
614     \arg        ADC_EXTTRIG_REGULAR_T7_CH0: external trigger timer 7 CC0 event select for regular channel
615     \arg        ADC_EXTTRIG_REGULAR_T7_TRGO: external trigger timer 7 TRGO event select for regular channel
616     \arg        ADC_EXTTRIG_REGULAR_EXTI_11: external trigger extiline 11 select for regular channel
617                 for inserted channel:
618                 only one parameter can be selected which is shown as below:
619     \arg        ADC_EXTTRIG_INSERTED_T0_CH3: timer0 capture compare 3
620     \arg        ADC_EXTTRIG_INSERTED_T0_TRGO: timer0 TRGO event
621     \arg        ADC_EXTTRIG_INSERTED_T1_CH0: timer1 capture compare 0
622     \arg        ADC_EXTTRIG_INSERTED_T1_TRGO: timer1 TRGO event
623     \arg        ADC_EXTTRIG_INSERTED_T2_CH1: timer2 capture compare 1
624     \arg        ADC_EXTTRIG_INSERTED_T2_CH3: timer2 capture compare 3
625     \arg        ADC_EXTTRIG_INSERTED_T3_CH0: timer3 capture compare 0
626     \arg        ADC_EXTTRIG_INSERTED_T3_CH1: timer3 capture compare 1
627     \arg        ADC_EXTTRIG_INSERTED_T3_CH2: timer3 capture compare 2
628     \arg        ADC_EXTTRIG_INSERTED_T3_TRGO: timer3 capture compare TRGO
629     \arg        ADC_EXTTRIG_INSERTED_T4_CH3: timer4 capture compare 3
630     \arg        ADC_EXTTRIG_INSERTED_T4_TRGO: timer4 capture compare TRGO
631     \arg        ADC_EXTTRIG_INSERTED_T7_CH1: timer7 capture compare 1
632     \arg        ADC_EXTTRIG_INSERTED_T7_CH2: timer7 capture compare 2
633     \arg        ADC_EXTTRIG_INSERTED_T7_CH3: timer7 capture compare 3
634     \arg        ADC_EXTTRIG_INSERTED_EXTI_15: external interrupt line 15
635     \param[out] none
636     \retval     none
637 */
adc_external_trigger_source_config(uint32_t adc_periph,uint8_t adc_channel_group,uint32_t external_trigger_source)638 void adc_external_trigger_source_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t external_trigger_source)
639 {
640     switch(adc_channel_group) {
641     case ADC_REGULAR_CHANNEL:
642         /* configure ADC regular group external trigger source */
643         ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETSRC);
644         ADC_CTL1(adc_periph) |= (uint32_t)external_trigger_source;
645         break;
646     case ADC_INSERTED_CHANNEL:
647         /* configure ADC inserted group external trigger source */
648         ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETSIC);
649         ADC_CTL1(adc_periph) |= (uint32_t)external_trigger_source;
650         break;
651     default:
652         break;
653     }
654 }
655 
656 /*!
657     \brief      enable ADC external trigger
658     \param[in]  adc_periph: ADCx,x=0,1,2
659     \param[in]  adc_channel_group: select the channel group
660                 only one parameter can be selected which is shown as below:
661     \arg        ADC_REGULAR_CHANNEL: regular channel group
662     \arg        ADC_INSERTED_CHANNEL: inserted channel group
663     \param[in]  trigger_mode: external trigger mode
664                 only one parameter can be selected which is shown as below:
665     \arg        EXTERNAL_TRIGGER_DISABLE: external trigger disable
666     \arg        EXTERNAL_TRIGGER_RISING: rising edge of external trigger
667     \arg        EXTERNAL_TRIGGER_FALLING: falling edge of external trigger
668     \arg        EXTERNAL_TRIGGER_RISING_FALLING: rising and falling edge of external trigger
669     \param[out] none
670     \retval     none
671 */
adc_external_trigger_config(uint32_t adc_periph,uint8_t adc_channel_group,uint32_t trigger_mode)672 void adc_external_trigger_config(uint32_t adc_periph, uint8_t adc_channel_group, uint32_t trigger_mode)
673 {
674     switch(adc_channel_group) {
675     case ADC_REGULAR_CHANNEL:
676         /* configure ADC regular channel group external trigger mode */
677         ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_ETMRC);
678         ADC_CTL1(adc_periph) |= (uint32_t)(trigger_mode << REGULAR_TRIGGER_MODE);
679         break;
680     case ADC_INSERTED_CHANNEL:
681         /* configure ADC inserted channel group external trigger mode */
682         ADC_CTL1(adc_periph) &=  ~((uint32_t)ADC_CTL1_ETMIC);
683         ADC_CTL1(adc_periph) |= (uint32_t)(trigger_mode << INSERTED_TRIGGER_MODE);
684         break;
685     default:
686         break;
687     }
688 }
689 
690 /*!
691     \brief      enable ADC software trigger
692     \param[in]  adc_periph: ADCx,x=0,1,2
693     \param[in]  adc_channel_group: select the channel group
694                 only one parameter can be selected which is shown as below:
695     \arg        ADC_REGULAR_CHANNEL: regular channel group
696     \arg        ADC_INSERTED_CHANNEL: inserted channel group
697     \param[out] none
698     \retval     none
699 */
adc_software_trigger_enable(uint32_t adc_periph,uint8_t adc_channel_group)700 void adc_software_trigger_enable(uint32_t adc_periph, uint8_t adc_channel_group)
701 {
702     switch(adc_channel_group) {
703     case ADC_REGULAR_CHANNEL:
704         /* enable ADC regular channel group software trigger */
705         ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_SWRCST;
706         break;
707     case ADC_INSERTED_CHANNEL:
708         /* enable ADC inserted channel group software trigger */
709         ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_SWICST;
710         break;
711     default:
712         break;
713     }
714 }
715 
716 /*!
717     \brief      configure end of conversion mode
718     \param[in]  adc_periph: ADCx,x=0,1,2
719     \param[in]  end_selection: end of conversion mode
720                 only one parameter can be selected which is shown as below:
721     \arg        ADC_EOC_SET_SEQUENCE: only at the end of a sequence of regular conversions, the EOC bit is set.Overflow detection is disabled unless DMA=1.
722     \arg        ADC_EOC_SET_CONVERSION: at the end of each regular conversion, the EOC bit is set.Overflow is detected automatically.
723     \param[out] none
724     \retval     none
725 */
adc_end_of_conversion_config(uint32_t adc_periph,uint8_t end_selection)726 void adc_end_of_conversion_config(uint32_t adc_periph, uint8_t end_selection)
727 {
728     switch(end_selection) {
729     case ADC_EOC_SET_SEQUENCE:
730         /* only at the end of a sequence of regular conversions, the EOC bit is set */
731         ADC_CTL1(adc_periph) &= ~((uint32_t)ADC_CTL1_EOCM);
732         break;
733     case ADC_EOC_SET_CONVERSION:
734         /* at the end of each regular conversion, the EOC bit is set.Overflow is detected automatically */
735         ADC_CTL1(adc_periph) |= (uint32_t)(ADC_CTL1_EOCM);
736         break;
737     default:
738         break;
739     }
740 }
741 
742 /*!
743     \brief      read ADC regular group data register
744     \param[in]  adc_periph: ADCx,x=0,1,2
745     \param[in]  none
746     \param[out] none
747     \retval     the conversion value
748 */
adc_regular_data_read(uint32_t adc_periph)749 uint16_t adc_regular_data_read(uint32_t adc_periph)
750 {
751     return (uint16_t)(ADC_RDATA(adc_periph));
752 }
753 
754 /*!
755     \brief      read ADC inserted group data register
756     \param[in]  adc_periph: ADCx,x=0,1,2
757     \param[in]  inserted_channel : insert channel select
758                 only one parameter can be selected which is shown as below:
759     \arg        ADC_INSERTED_CHANNEL_0: inserted Channel0
760     \arg        ADC_INSERTED_CHANNEL_1: inserted channel1
761     \arg        ADC_INSERTED_CHANNEL_2: inserted Channel2
762     \arg        ADC_INSERTED_CHANNEL_3: inserted Channel3
763     \param[out] none
764     \retval     the conversion value
765 */
adc_inserted_data_read(uint32_t adc_periph,uint8_t inserted_channel)766 uint16_t adc_inserted_data_read(uint32_t adc_periph, uint8_t inserted_channel)
767 {
768     uint32_t idata;
769     /* read the data of the selected channel */
770     switch(inserted_channel) {
771     case ADC_INSERTED_CHANNEL_0:
772         /* read the data of channel 0 */
773         idata = ADC_IDATA0(adc_periph);
774         break;
775     case ADC_INSERTED_CHANNEL_1:
776         /* read the data of channel 1 */
777         idata = ADC_IDATA1(adc_periph);
778         break;
779     case ADC_INSERTED_CHANNEL_2:
780         /* read the data of channel 2 */
781         idata = ADC_IDATA2(adc_periph);
782         break;
783     case ADC_INSERTED_CHANNEL_3:
784         /* read the data of channel 3 */
785         idata = ADC_IDATA3(adc_periph);
786         break;
787     default:
788         idata = 0U;
789         break;
790     }
791     return (uint16_t)idata;
792 }
793 
794 /*!
795     \brief      disable ADC analog watchdog single channel
796     \param[in]  adc_periph: ADCx,x=0,1,2
797     \param[out] none
798     \retval     none
799 */
adc_watchdog_single_channel_disable(uint32_t adc_periph)800 void adc_watchdog_single_channel_disable(uint32_t adc_periph)
801 {
802     ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_WDSC);
803 }
804 
805 /*!
806     \brief      enable ADC analog watchdog single channel
807     \param[in]  adc_periph: ADCx,x=0,1,2
808     \param[in]  adc_channel: the selected ADC channel
809                 only one parameter can be selected which is shown as below:
810     \arg        ADC_CHANNEL_x: ADC Channelx(x=0..18)
811     \param[out] none
812     \retval     none
813 */
adc_watchdog_single_channel_enable(uint32_t adc_periph,uint8_t adc_channel)814 void adc_watchdog_single_channel_enable(uint32_t adc_periph, uint8_t adc_channel)
815 {
816     ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_WDCHSEL);
817 
818     /* analog watchdog channel select */
819     ADC_CTL0(adc_periph) |= (uint32_t)adc_channel;
820     ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_WDSC;
821 }
822 
823 /*!
824     \brief      configure ADC analog watchdog group channel
825     \param[in]  adc_periph: ADCx,x=0,1,2
826     \param[in]  adc_channel_group: the channel group use analog watchdog
827                 only one parameter can be selected which is shown as below:
828     \arg        ADC_REGULAR_CHANNEL: regular channel group
829     \arg        ADC_INSERTED_CHANNEL: inserted channel group
830     \arg        ADC_REGULAR_INSERTED_CHANNEL: both regular and inserted group
831     \param[out] none
832     \retval     none
833 */
adc_watchdog_group_channel_enable(uint32_t adc_periph,uint8_t adc_channel_group)834 void adc_watchdog_group_channel_enable(uint32_t adc_periph, uint8_t adc_channel_group)
835 {
836     ADC_CTL0(adc_periph) &= ~((uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC));
837     /* select the group */
838     switch(adc_channel_group) {
839     case ADC_REGULAR_CHANNEL:
840         /* regular channel analog watchdog enable */
841         ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_RWDEN;
842         break;
843     case ADC_INSERTED_CHANNEL:
844         /* inserted channel analog watchdog enable */
845         ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_IWDEN;
846         break;
847     case ADC_REGULAR_INSERTED_CHANNEL:
848         /* regular and inserted channel analog watchdog enable */
849         ADC_CTL0(adc_periph) |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN);
850         break;
851     default:
852         break;
853     }
854 }
855 
856 /*!
857     \brief      disable ADC analog watchdog
858     \param[in]  adc_periph: ADCx,x=0,1,2
859     \param[in]  adc_channel_group: the channel group use analog watchdog
860                 only one parameter can be selected which is shown as below:
861     \arg        ADC_REGULAR_CHANNEL: regular channel group
862     \arg        ADC_INSERTED_CHANNEL: inserted channel group
863     \arg        ADC_REGULAR_INSERTED_CHANNEL: both regular and inserted group
864     \param[out] none
865     \retval     none
866 */
adc_watchdog_disable(uint32_t adc_periph,uint8_t adc_channel_group)867 void adc_watchdog_disable(uint32_t adc_periph, uint8_t adc_channel_group)
868 {
869     /* select the group */
870     switch(adc_channel_group) {
871     case ADC_REGULAR_CHANNEL:
872         /* disable ADC analog watchdog regular channel group */
873         ADC_CTL0(adc_periph) &=  ~((uint32_t)ADC_CTL0_RWDEN);
874         break;
875     case ADC_INSERTED_CHANNEL:
876         /* disable ADC analog watchdog inserted channel group */
877         ADC_CTL0(adc_periph) &=  ~((uint32_t)ADC_CTL0_IWDEN);
878         break;
879     case ADC_REGULAR_INSERTED_CHANNEL:
880         /* disable ADC analog watchdog regular and inserted channel group */
881         ADC_CTL0(adc_periph) &=  ~((uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN));
882         break;
883     default:
884         break;
885     }
886 }
887 
888 /*!
889     \brief      configure ADC analog watchdog threshold
890     \param[in]  adc_periph: ADCx,x=0,1,2
891     \param[in]  low_threshold: analog watchdog low threshold,0..4095
892     \param[in]  high_threshold: analog watchdog high threshold,0..4095
893     \param[out] none
894     \retval     none
895 */
adc_watchdog_threshold_config(uint32_t adc_periph,uint16_t low_threshold,uint16_t high_threshold)896 void adc_watchdog_threshold_config(uint32_t adc_periph, uint16_t low_threshold, uint16_t high_threshold)
897 {
898     /* configure ADC analog watchdog low threshold */
899     ADC_WDLT(adc_periph) = (uint32_t)WDLT_WDLT(low_threshold);
900     /* configure ADC analog watchdog high threshold */
901     ADC_WDHT(adc_periph) = (uint32_t)WDHT_WDHT(high_threshold);
902 }
903 
904 /*!
905     \brief      get the ADC flag bits
906     \param[in]  adc_periph: ADCx,x=0,1,2
907     \param[in]  adc_flag: the adc flag bits
908                 only one parameter can be selected which is shown as below:
909     \arg        ADC_FLAG_WDE: analog watchdog event flag
910     \arg        ADC_FLAG_EOC: end of group conversion flag
911     \arg        ADC_FLAG_EOIC: end of inserted group conversion flag
912     \arg        ADC_FLAG_STIC: start flag of inserted channel group
913     \arg        ADC_FLAG_STRC: start flag of regular channel group
914     \arg        ADC_FLAG_ROVF: regular data register overflow flag
915     \param[out] none
916     \retval     FlagStatus: SET or RESET
917 */
adc_flag_get(uint32_t adc_periph,uint32_t adc_flag)918 FlagStatus adc_flag_get(uint32_t adc_periph, uint32_t adc_flag)
919 {
920     FlagStatus reval = RESET;
921     if(ADC_STAT(adc_periph) & adc_flag) {
922         reval = SET;
923     }
924     return reval;
925 
926 }
927 
928 /*!
929     \brief      clear the ADC flag bits
930     \param[in]  adc_periph: ADCx,x=0,1,2
931     \param[in]  adc_flag: the adc flag bits
932                 only one parameter can be selected which is shown as below:
933     \arg        ADC_FLAG_WDE: analog watchdog event flag
934     \arg        ADC_FLAG_EOC: end of group conversion flag
935     \arg        ADC_FLAG_EOIC: end of inserted group conversion flag
936     \arg        ADC_FLAG_STIC: start flag of inserted channel group
937     \arg        ADC_FLAG_STRC: start flag of regular channel group
938     \arg        ADC_FLAG_ROVF: regular data register overflow flag
939     \param[out] none
940     \retval     none
941 */
adc_flag_clear(uint32_t adc_periph,uint32_t adc_flag)942 void adc_flag_clear(uint32_t adc_periph, uint32_t adc_flag)
943 {
944     ADC_STAT(adc_periph) &= ~((uint32_t)adc_flag);
945 }
946 
947 /*!
948     \brief      get the bit state of ADCx software start conversion
949     \param[in]  adc_periph: ADCx, x=0,1,2 only one among these parameters can be selected
950     \param[in]  none
951     \param[out] none
952     \retval     FlagStatus: SET or RESET
953 */
adc_regular_software_startconv_flag_get(uint32_t adc_periph)954 FlagStatus adc_regular_software_startconv_flag_get(uint32_t adc_periph)
955 {
956     FlagStatus reval = RESET;
957     if((uint32_t)RESET != (ADC_STAT(adc_periph) & ADC_STAT_STRC)) {
958         reval = SET;
959     }
960     return reval;
961 }
962 
963 /*!
964     \brief      get the bit state of ADCx software inserted channel start conversion
965     \param[in]  adc_periph: ADCx, x=0,1,2 only one among these parameters can be selected
966     \param[in]  none
967     \param[out] none
968     \retval     FlagStatus: SET or RESET
969 */
adc_inserted_software_startconv_flag_get(uint32_t adc_periph)970 FlagStatus adc_inserted_software_startconv_flag_get(uint32_t adc_periph)
971 {
972     FlagStatus reval = RESET;
973     if((uint32_t)RESET != (ADC_STAT(adc_periph) & ADC_STAT_STIC)) {
974         reval = SET;
975     }
976     return reval;
977 }
978 
979 /*!
980     \brief      get the ADC interrupt bits
981     \param[in]  adc_periph: ADCx,x=0,1,2
982     \param[in]  adc_interrupt: the adc interrupt bits
983                 only one parameter can be selected which is shown as below:
984     \arg        ADC_INT_FLAG_WDE: analog watchdog interrupt
985     \arg        ADC_INT_FLAG_EOC: end of group conversion interrupt
986     \arg        ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt
987     \arg        ADC_INT_FLAG_ROVF: regular data register overflow interrupt
988     \param[out] none
989     \retval     FlagStatus: SET or RESET
990 */
adc_interrupt_flag_get(uint32_t adc_periph,uint32_t adc_interrupt)991 FlagStatus adc_interrupt_flag_get(uint32_t adc_periph, uint32_t adc_interrupt)
992 {
993     FlagStatus interrupt_flag = RESET;
994     uint32_t state;
995     /* check the interrupt bits */
996     switch(adc_interrupt) {
997     case ADC_INT_FLAG_WDE:
998         /* get the ADC analog watchdog interrupt bits */
999         state = ADC_STAT(adc_periph) & ADC_STAT_WDE;
1000         if((ADC_CTL0(adc_periph) & ADC_CTL0_WDEIE) && state) {
1001             interrupt_flag = SET;
1002         }
1003         break;
1004     case ADC_INT_FLAG_EOC:
1005         /* get the ADC end of group conversion interrupt bits */
1006         state = ADC_STAT(adc_periph) & ADC_STAT_EOC;
1007         if((ADC_CTL0(adc_periph) & ADC_CTL0_EOCIE) && state) {
1008             interrupt_flag = SET;
1009         }
1010         break;
1011     case ADC_INT_FLAG_EOIC:
1012         /* get the ADC end of inserted group conversion interrupt bits */
1013         state = ADC_STAT(adc_periph) & ADC_STAT_EOIC;
1014         if((ADC_CTL0(adc_periph) & ADC_CTL0_EOICIE) && state) {
1015             interrupt_flag = SET;
1016         }
1017         break;
1018     case ADC_INT_FLAG_ROVF:
1019         /* get the ADC regular data register overflow interrupt bits */
1020         state = ADC_STAT(adc_periph) & ADC_STAT_ROVF;
1021         if((ADC_CTL0(adc_periph) & ADC_CTL0_ROVFIE) && state) {
1022             interrupt_flag = SET;
1023         }
1024         break;
1025     default:
1026         break;
1027     }
1028     return interrupt_flag;
1029 }
1030 
1031 /*!
1032     \brief      clear the ADC flag
1033     \param[in]  adc_periph: ADCx,x=0,1,2
1034     \param[in]  adc_interrupt: the adc status flag
1035                 only one parameter can be selected which is shown as below:
1036     \arg        ADC_INT_FLAG_WDE: analog watchdog interrupt
1037     \arg        ADC_INT_FLAG_EOC: end of group conversion interrupt
1038     \arg        ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt
1039     \arg        ADC_INT_FLAG_ROVF: regular data register overflow interrupt
1040     \param[out] none
1041     \retval     none
1042 */
adc_interrupt_flag_clear(uint32_t adc_periph,uint32_t adc_interrupt)1043 void adc_interrupt_flag_clear(uint32_t adc_periph, uint32_t adc_interrupt)
1044 {
1045     ADC_STAT(adc_periph) &= ~((uint32_t)adc_interrupt);
1046 }
1047 
1048 /*!
1049     \brief      enable ADC interrupt
1050     \param[in]  adc_periph: ADCx,x=0,1,2
1051     \param[in]  adc_interrupt: the adc interrupt flag
1052                 only one parameter can be selected which is shown as below:
1053     \arg        ADC_INT_WDE: analog watchdog interrupt flag
1054     \arg        ADC_INT_EOC: end of group conversion interrupt flag
1055     \arg        ADC_INT_EOIC: end of inserted group conversion interrupt flag
1056     \arg        ADC_INT_ROVF: regular data register overflow interrupt flag
1057     \param[out] none
1058     \retval     none
1059 */
adc_interrupt_enable(uint32_t adc_periph,uint32_t adc_interrupt)1060 void adc_interrupt_enable(uint32_t adc_periph, uint32_t adc_interrupt)
1061 {
1062     switch(adc_interrupt) {
1063     case ADC_INT_WDE:
1064         /* enable analog watchdog interrupt */
1065         ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_WDEIE;
1066         break;
1067     case ADC_INT_EOC:
1068         /* enable end of group conversion interrupt */
1069         ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_EOCIE;
1070         break;
1071     case ADC_INT_EOIC:
1072         /* enable end of inserted group conversion interrupt */
1073         ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_EOICIE;
1074         break;
1075     case ADC_INT_ROVF:
1076         ADC_CTL0(adc_periph) |= (uint32_t) ADC_CTL0_ROVFIE;
1077         break;
1078     default:
1079         break;
1080     }
1081 }
1082 
1083 /*!
1084     \brief      disable ADC interrupt
1085     \param[in]  adc_periph: ADCx,x=0,1,2
1086     \param[in]  adc_flag: the adc interrupt flag
1087                 only one parameter can be selected which is shown as below:
1088       \arg      ADC_INT_WDE: analog watchdog interrupt flag
1089       \arg      ADC_INT_EOC: end of group conversion interrupt flag
1090       \arg      ADC_INT_EOIC: end of inserted group conversion interrupt flag
1091       \arg      ADC_INT_ROVF: regular data register overflow interrupt flag
1092     \param[out] none
1093     \retval     none
1094 */
adc_interrupt_disable(uint32_t adc_periph,uint32_t adc_interrupt)1095 void adc_interrupt_disable(uint32_t adc_periph, uint32_t adc_interrupt)
1096 {
1097     switch(adc_interrupt) {
1098     /* select the interrupt source */
1099     case ADC_INT_WDE:
1100         ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_WDEIE);
1101         break;
1102     case ADC_INT_EOC:
1103         ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_EOCIE);
1104         break;
1105     case ADC_INT_EOIC:
1106         ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_EOICIE);
1107         break;
1108     case ADC_INT_ROVF:
1109         ADC_CTL0(adc_periph) &= ~((uint32_t)ADC_CTL0_ROVFIE);
1110         break;
1111     default:
1112         break;
1113     }
1114 }
1115 
1116 /*!
1117     \brief      configure the ADC sync mode
1118     \param[in]  sync_mode: ADC sync mode
1119                 only one parameter can be selected which is shown as below:
1120     \arg        ADC_SYNC_MODE_INDEPENDENT: all the ADCs work independently
1121     \arg        ADC_DAUL_REGULAL_PARALLEL_INSERTED_PARALLEL: ADC0 and ADC1 work in combined regular parallel & inserted parallel mode
1122     \arg        ADC_DAUL_REGULAL_PARALLEL_INSERTED_ROTATION: ADC0 and ADC1 work in combined regular parallel & trigger rotation mode
1123     \arg        ADC_DAUL_INSERTED_PARALLEL: ADC0 and ADC1 work in inserted parallel mode
1124     \arg        ADC_DAUL_REGULAL_PARALLEL: ADC0 and ADC1 work in regular parallel mode
1125     \arg        ADC_DAUL_REGULAL_FOLLOW_UP: ADC0 and ADC1 work in follow-up mode
1126     \arg        ADC_DAUL_INSERTED_TRRIGGER_ROTATION: ADC0 and ADC1 work in trigger rotation mode
1127     \arg        ADC_ALL_REGULAL_PARALLEL_INSERTED_PARALLEL: all ADCs work in combined regular parallel & inserted parallel mode
1128     \arg        ADC_ALL_REGULAL_PARALLEL_INSERTED_ROTATION: all ADCs work in combined regular parallel & trigger rotation mode
1129     \arg        ADC_ALL_INSERTED_PARALLEL: all ADCs work in inserted parallel mode
1130     \arg        ADC_ALL_REGULAL_PARALLEL: all ADCs work in regular parallel mode
1131     \arg        ADC_ALL_REGULAL_FOLLOW_UP: all ADCs work in follow-up mode
1132     \arg        ADC_ALL_INSERTED_TRRIGGER_ROTATION: all ADCs work in trigger rotation mode
1133     \param[out] none
1134     \retval     none
1135 */
adc_sync_mode_config(uint32_t sync_mode)1136 void adc_sync_mode_config(uint32_t sync_mode)
1137 {
1138     ADC_SYNCCTL &= ~(ADC_SYNCCTL_SYNCM);
1139     ADC_SYNCCTL |= sync_mode;
1140 }
1141 
1142 /*!
1143     \brief      configure the delay between 2 sampling phases in ADC sync modes
1144     \param[in]  sample_delay:  the delay between 2 sampling phases in ADC sync modes
1145                 only one parameter can be selected which is shown as below:
1146       \arg      ADC_SYNC_DELAY_xCYCLE: x=5..20,the delay between 2 sampling phases in ADC sync modes is x ADC clock cycles
1147     \param[out] none
1148     \retval     none
1149 */
adc_sync_delay_config(uint32_t sample_delay)1150 void adc_sync_delay_config(uint32_t sample_delay)
1151 {
1152     ADC_SYNCCTL &= ~(ADC_SYNCCTL_SYNCDLY);
1153     ADC_SYNCCTL |= sample_delay;
1154 }
1155 
1156 /*!
1157     \brief      configure ADC sync DMA mode selection
1158     \param[in]  dma_mode:  ADC sync DMA mode
1159                 only one parameter can be selected which is shown as below:
1160     \arg        ADC_SYNC_DMA_DISABLE: ADC sync DMA disabled
1161     \arg        ADC_SYNC_DMA_MODE0: ADC sync DMA mode 0
1162     \arg        ADC_SYNC_DMA_MODE1: ADC sync DMA mode 1
1163     \param[out] none
1164     \retval     none
1165 */
adc_sync_dma_config(uint32_t dma_mode)1166 void adc_sync_dma_config(uint32_t dma_mode)
1167 {
1168     ADC_SYNCCTL &= ~(ADC_SYNCCTL_SYNCDMA);
1169     ADC_SYNCCTL |= dma_mode;
1170 }
1171 
1172 /*!
1173     \brief      configure ADC sync DMA engine is disabled after the end of transfer signal from DMA controller is detected
1174     \param[in]  none
1175     \param[out] none
1176     \retval     none
1177 */
adc_sync_dma_request_after_last_enable(void)1178 void adc_sync_dma_request_after_last_enable(void)
1179 {
1180     ADC_SYNCCTL |= ADC_SYNCCTL_SYNCDDM;
1181 }
1182 
1183 /*!
1184     \brief      configure ADC sync DMA engine issues requests according to the SYNCDMA bits
1185     \param[in]  none
1186     \param[out] none
1187     \retval     none
1188 */
adc_sync_dma_request_after_last_disable(void)1189 void adc_sync_dma_request_after_last_disable(void)
1190 {
1191     ADC_SYNCCTL &= ~(ADC_SYNCCTL_SYNCDDM);
1192 }
1193 
1194 /*!
1195     \brief      read ADC sync regular data register
1196     \param[in]  none
1197     \param[out] none
1198     \retval     sync regular data
1199 */
adc_sync_regular_data_read(void)1200 uint32_t adc_sync_regular_data_read(void)
1201 {
1202     return (uint32_t)ADC_SYNCDATA;
1203 }
1204