1 /*!
2  * @file        apm32f4xx_adc.c
3  *
4  * @brief       This file contains all the functions for the ADC peripheral
5  *
6  * @version     V1.0.2
7  *
8  * @date        2022-06-23
9  *
10  * @attention
11  *
12  *  Copyright (C) 2021-2022 Geehy Semiconductor
13  *
14  *  You may not use this file except in compliance with the
15  *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
16  *
17  *  The program is only for reference, which is distributed in the hope
18  *  that it will be usefull and instructional for customers to develop
19  *  their software. Unless required by applicable law or agreed to in
20  *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
21  *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
22  *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
23  *  and limitations under the License.
24  */
25 
26 #include "apm32f4xx_adc.h"
27 #include "apm32f4xx_rcm.h"
28 
29 /** @addtogroup APM32F4xx_StdPeriphDriver
30   @{
31 */
32 
33 /** @defgroup ADC_Driver
34   * @brief ADC driver modules
35   @{
36 */
37 
38 /** @defgroup ADC_Functions
39   @{
40 */
41 
42 /*!
43  * @brief     Reset ADC peripheral registers to their default reset values.
44  *
45  * @param     None
46  *
47  * @retval    None
48  */
ADC_Reset(void)49 void ADC_Reset(void)
50 {
51     RCM_EnableAPB2PeriphReset(RCM_APB2_PERIPH_ADC);
52     RCM_DisableAPB2PeriphReset(RCM_APB2_PERIPH_ADC);
53 }
54 
55 /*!
56  * @brief     Config the ADC peripheral according to the specified parameters in the adcConfig.
57  *
58  * @param     adc: Select ADCx where x can be 1, 2 or 3.
59  *
60  * @param     adcConfig: pointer to a ADC_Config_T structure.
61  *
62  * @retval    None
63  */
ADC_Config(ADC_T * adc,ADC_Config_T * adcConfig)64 void ADC_Config(ADC_T *adc, ADC_Config_T *adcConfig)
65 {
66     adc->CTRL1_B.RESSEL = adcConfig->resolution;
67     adc->CTRL1_B.SCANEN = adcConfig->scanConvMode;
68 
69     adc->CTRL2_B.REGEXTTRGEN = adcConfig->extTrigEdge;
70     adc->CTRL2_B.REGEXTTRGSEL = adcConfig->extTrigConv;
71     adc->CTRL2_B.DALIGNCFG = adcConfig->dataAlign;
72     adc->CTRL2_B.CONTCEN = adcConfig->continuousConvMode;
73 
74     adc->REGSEQ1_B.REGSEQLEN = adcConfig->nbrOfChannel - 1;
75 }
76 
77 /*!
78  * @brief     Fills each ADC_Config_T member with its default value.
79  *
80  * @param     adcConfig: pointer to an ADC_Config_T structure.
81  *
82  * @retval    None
83  */
ADC_ConfigStructInit(ADC_Config_T * adcConfig)84 void ADC_ConfigStructInit(ADC_Config_T *adcConfig)
85 {
86     adcConfig->resolution = ADC_RESOLUTION_12BIT;
87     adcConfig->scanConvMode = DISABLE;
88     adcConfig->continuousConvMode = DISABLE;
89     adcConfig->extTrigEdge = ADC_EXT_TRIG_EDGE_NONE;
90     adcConfig->extTrigConv = ADC_EXT_TRIG_CONV_TMR1_CC1;
91     adcConfig->dataAlign = ADC_DATA_ALIGN_RIGHT;
92     adcConfig->nbrOfChannel = 1;
93 }
94 
95 /*!
96  * @brief     Config the ADCs peripherals according to the specified parameters in
97  *             the adcCommonConfig.
98  *
99  * @param     adcCommonConfig: pointer to an ADC_CommonConfig_T structure
100  *
101  * @retval    None
102  */
ADC_CommonConfig(ADC_CommonConfig_T * adcCommonConfig)103 void ADC_CommonConfig(ADC_CommonConfig_T *adcCommonConfig)
104 {
105     ADC->CCTRL_B.ADCMSEL = adcCommonConfig->mode;
106     ADC->CCTRL_B.ADCPRE = adcCommonConfig->prescaler;
107     ADC->CCTRL_B.DMAMODE = adcCommonConfig->accessMode;
108     ADC->CCTRL_B.SMPDEL2 = adcCommonConfig->twoSampling;
109 }
110 
111 /*!
112  * @brief     Fills each ADC_CommonInitStruct member with its default value.
113  *
114  * @param     adccommonconfig: pointer to an ADC_CommonInitTypeDef structure.
115  *
116  * @retval    None
117  */
ADC_CommonConfigStructInit(ADC_CommonConfig_T * adccommonconfig)118 void ADC_CommonConfigStructInit(ADC_CommonConfig_T *adccommonconfig)
119 {
120     adccommonconfig->mode = ADC_MODE_INDEPENDENT;
121     adccommonconfig->prescaler = ADC_PRESCALER_DIV2;
122     adccommonconfig->accessMode = ADC_ACCESS_MODE_DISABLED;
123     adccommonconfig->twoSampling = ADC_TWO_SAMPLING_5CYCLES;
124 }
125 
126 /*!
127  * @brief     Enables the specified ADC peripheral.
128  *
129  * @param     adc: Select ADCx where x can be 1, 2 or 3.
130  *
131  * @retval    None
132  */
ADC_Enable(ADC_T * adc)133 void ADC_Enable(ADC_T *adc)
134 {
135     adc->CTRL2_B.ADCEN = BIT_SET;
136 }
137 
138 /*!
139  * @brief     Disable the specified ADC peripheral.
140  *
141  * @param     adc: Select ADCx where x can be 1, 2 or 3.
142  *
143  * @retval    None
144  */
ADC_Disable(ADC_T * adc)145 void ADC_Disable(ADC_T *adc)
146 {
147     adc->CTRL2_B.ADCEN = BIT_RESET;
148 }
149 
150 /*!
151  * @brief     Enable the specified ADC analog watchdog.
152  *
153  * @param     adc: Select ADCx where x can be 1, 2 or 3.
154  *
155  * @param     analogWatchdog: The ADC analog watchdog configuration
156  *               This parameter can be one of the following values:
157  *               @arg ADC_ANALOG_WATCHDOG_SINGLE_REG        : Analog watchdog on a single regular channel
158  *               @arg ADC_ANALOG_WATCHDOG_SINGLE_INJEC      : Analog watchdog on a single injected channel
159  *               @arg ADC_ANALOG_WATCHDOG_SINGLE_REG_INJEC  : Analog watchdog on a single regular or injected channel
160  *               @arg ADC_ANALOG_WATCHDOG_ALL_REG           : Analog watchdog on  all regular channel
161  *               @arg ADC_ANALOG_WATCHDOG_ALL_INJEC         : Analog watchdog on  all injected channel
162  *               @arg ADC_ANALOG_WATCHDOG_ALL_REG_ALL_INJEC : Analog watchdog on all regular and injected channels
163  *
164  * @retval    None
165  */
ADC_EnableAnalogWatchdog(ADC_T * adc,ADC_ANALOG_WATCHDOG_T analogWatchdog)166 void ADC_EnableAnalogWatchdog(ADC_T *adc, ADC_ANALOG_WATCHDOG_T analogWatchdog)
167 {
168     adc->CTRL1_B.INJAWDEN = analogWatchdog & 0x01;
169     adc->CTRL1_B.REGAWDEN = (analogWatchdog >> 1) & 0x01;
170     adc->CTRL1_B.AWDSGLEN = analogWatchdog >> 4;
171 }
172 
173 /*!
174  * @brief     Disable the specified ADC analog watchdog.
175  *
176  * @param     adc: Select ADCx where x can be 1, 2 or 3.
177  *
178  * @retval    None
179  */
ADC_DisableAnalogWatchdog(ADC_T * adc)180 void ADC_DisableAnalogWatchdog(ADC_T *adc)
181 {
182     adc->CTRL1_B.AWDSGLEN = BIT_RESET;
183     adc->CTRL1_B.INJAWDEN = BIT_RESET;
184     adc->CTRL1_B.REGAWDEN = BIT_RESET;
185 }
186 
187 /*!
188  * @brief     Configures the specified ADC high and low thresholds of the analog watchdog.
189  *
190  * @param     adc: Select ADCx where x can be 1, 2 or 3.
191  *
192  * @param     highThreshold: The ADC analog watchdog High threshold value.
193  *                           This parameter must be a 12bit value.
194  *
195  * @param     lowThreshold:  The ADC analog watchdog Low threshold value.
196  *                           This parameter must be a 12bit value.
197  * @retval    None
198  */
ADC_ConfigAnalogWatchdogThresholds(ADC_T * adc,uint16_t highThreshold,uint16_t lowThreshold)199 void ADC_ConfigAnalogWatchdogThresholds(ADC_T *adc, uint16_t highThreshold, uint16_t lowThreshold)
200 {
201     adc->AWDHT = highThreshold;
202     adc->AWDLT = lowThreshold;
203 }
204 
205 /*!
206  * @brief     Configures the specified ADC high and low thresholds of the analog watchdog.
207  *
208  * @param     adc: Select ADCx where x can be 1, 2 or 3.
209  *
210  * @param     lowThreshold: The ADC analog watchdog Low threshold value.
211  *                          This parameter must be a 12bit value.
212  *
213  * @retval    None
214  */
ADC_AnalogWatchdogLowThresholds(ADC_T * adc,uint16_t lowThreshold)215 void ADC_AnalogWatchdogLowThresholds(ADC_T *adc,  uint16_t lowThreshold)
216 {
217     adc->AWDLT = lowThreshold;
218 }
219 
220 /*!
221  * @brief      Configures the specified ADC analog watchdog guarded single channel
222  *
223  * @param      adc: Select the ADC peripheral
224  *
225  * @param      channel: Select the ADC channel
226  *                      This parameter can be one of the following values:
227  *                        @arg ADC_CHANNEL_0:   Select ADC Channel 0
228  *                        @arg ADC_CHANNEL_1:   Select ADC Channel 1
229  *                        @arg ADC_CHANNEL_2:   Select ADC Channel 2
230  *                        @arg ADC_CHANNEL_3:   Select ADC Channel 3
231  *                        @arg ADC_CHANNEL_4:   Select ADC Channel 4
232  *                        @arg ADC_CHANNEL_5:   Select ADC Channel 5
233  *                        @arg ADC_CHANNEL_6:   Select ADC Channel 6
234  *                        @arg ADC_CHANNEL_7:   Select ADC Channel 7
235  *                        @arg ADC_CHANNEL_8:   Select ADC Channel 8
236  *                        @arg ADC_CHANNEL_9:   Select ADC Channel 9
237  *                        @arg ADC_CHANNEL_10:  Select ADC Channel 10
238  *                        @arg ADC_CHANNEL_11:  Select ADC Channel 11
239  *                        @arg ADC_CHANNEL_12:  Select ADC Channel 12
240  *                        @arg ADC_CHANNEL_13:  Select ADC Channel 13
241  *                        @arg ADC_CHANNEL_14:  Select ADC Channel 14
242  *                        @arg ADC_CHANNEL_15:  Select ADC Channel 15
243  *                        @arg ADC_CHANNEL_16:  Select ADC Channel 16
244  *                        @arg ADC_CHANNEL_17:  Select ADC Channel 17
245  *                        @arg ADC_CHANNEL_18:  Select ADC Channel 18
246  *
247  * @retval     None
248  *
249  * @note       adc can be ADC1, ADC2 or ADC3.
250  */
ADC_ConfigAnalogWatchdogSingleChannel(ADC_T * adc,uint8_t channel)251 void ADC_ConfigAnalogWatchdogSingleChannel(ADC_T *adc, uint8_t channel)
252 {
253     adc->CTRL1_B.AWDCHSEL = channel;
254 }
255 
256 /*!
257  * @brief     Enables the temperature sensor and Vrefint channels.
258  *
259  * @param     None
260  *
261  * @retval    None
262  */
ADC_EnableTempSensorVrefint(void)263 void ADC_EnableTempSensorVrefint(void)
264 {
265     ADC->CCTRL_B.TSVREFEN = BIT_SET;
266 }
267 
268 /*!
269  * @brief     Disable the temperature sensor and Vrefint channel.
270  *
271  * @param     None
272  *
273  * @retval    None
274  */
ADC_DisableTempSensorVrefint(void)275 void ADC_DisableTempSensorVrefint(void)
276 {
277     ADC->CCTRL_B.TSVREFEN = BIT_RESET;
278 }
279 
280 /*!
281  * @brief     Enables  the VBAT (Voltage Battery) channel.
282  *
283  * @param     None
284  *
285  * @retval    None
286  */
ADC_EnableVbat(void)287 void ADC_EnableVbat(void)
288 {
289     ADC->CCTRL_B.VBATEN = BIT_SET;
290 }
291 
292 /*!
293  * @brief     Disables the VBAT (Voltage Battery) channel.
294  *
295  * @param     None
296  *
297  * @retval    None
298  */
ADC_DisableVbat(void)299 void ADC_DisableVbat(void)
300 {
301     ADC->CCTRL_B.VBATEN = BIT_RESET;
302 }
303 
304 /*!
305  * @brief     Configures the specified ADC regular channel.
306  *
307  * @param     adc: Select ADCx where x can be 1, 2 or 3.
308  *
309  * @param     channel: the ADC channel to configure.
310  *                     This parameter can be one of the following values:
311  *                     @arg ADC_CHANNEL_0:  ADC channel 0
312  *                     @arg ADC_CHANNEL_1:  ADC channel 1
313  *                     @arg ADC_CHANNEL_2:  ADC channel 2
314  *                     @arg ADC_CHANNEL_3:  ADC channel 3
315  *                     @arg ADC_CHANNEL_4:  ADC channel 4
316  *                     @arg ADC_CHANNEL_5:  ADC channel 5
317  *                     @arg ADC_CHANNEL_6:  ADC channel 6
318  *                     @arg ADC_CHANNEL_7:  ADC channel 7
319  *                     @arg ADC_CHANNEL_8:  ADC channel 8
320  *                     @arg ADC_CHANNEL_9:  ADC channel 9
321  *                     @arg ADC_CHANNEL_10: ADC channel 10
322  *                     @arg ADC_CHANNEL_11: ADC channel 11
323  *                     @arg ADC_CHANNEL_12: ADC channel 12
324  *                     @arg ADC_CHANNEL_13: ADC channel 13
325  *                     @arg ADC_CHANNEL_14: ADC channel 14
326  *                     @arg ADC_CHANNEL_15: ADC channel 15
327  *                     @arg ADC_CHANNEL_16: ADC channel 16
328  *                     @arg ADC_CHANNEL_17: ADC channel 17
329  *                     @arg ADC_CHANNEL_18: ADC Channel 18
330  *
331  * @param     rank: The rank in the regular group sequencer
332  *                     This parameter must be between 1 to 16.
333  *
334  * @param     sampleTime: the specified ADC channel SampleTime
335  *                     The parameter can be one of following values:
336  *                     @arg ADC_SAMPLETIME_3CYCLES:   Sample time equal to 3 cycles
337  *                     @arg ADC_SAMPLETIME_15CYCLES:  Sample time equal to 15 cycles
338  *                     @arg ADC_SAMPLETIME_28CYCLES:  Sample time equal to 28 cycles
339  *                     @arg ADC_SAMPLETIME_56CYCLES:  Sample time equal to 56 cycles
340  *                     @arg ADC_SAMPLETIME_84CYCLES:  Sample time equal to 84 cycles
341  *                     @arg ADC_SAMPLETIME_112CYCLES: Sample time equal to 112 cycles
342  *                     @arg ADC_SAMPLETIME_144CYCLES: Sample time equal to 144 cycles
343  *                     @arg ADC_SAMPLETIME_480CYCLES: Sample time equal to 480 cycles
344  *
345  * @retval None
346  */
347 
ADC_ConfigRegularChannel(ADC_T * adc,uint8_t channel,uint8_t rank,uint8_t sampleTime)348 void ADC_ConfigRegularChannel(ADC_T *adc, uint8_t channel, uint8_t rank, uint8_t sampleTime)
349 {
350     uint32_t temp1 = 0;
351     uint32_t temp2 = 0;
352 
353     if (channel > ADC_CHANNEL_9)
354     {
355         temp1 = adc->SMPTIM1;
356         temp2 = (uint32_t)7 << (3 * (channel - 10));
357         temp1 &= ~temp2;
358         temp2 = (uint32_t)sampleTime << (3 * (channel - 10));
359         temp1 |= temp2;
360         adc->SMPTIM1 = temp1;
361     }
362     else
363     {
364         temp1 = adc->SMPTIM2;
365         temp2 = (uint32_t)7 << (3 * channel);
366         temp1 &= ~temp2;
367         temp2 = (uint32_t)sampleTime << (3 * channel);
368         temp1 |= temp2;
369         adc->SMPTIM2 = temp1;
370     }
371 
372     if (rank < 7)
373     {
374         temp1 = adc->REGSEQ3;
375         temp2 = (uint32_t)0x1F << (5 * (rank - 1));
376         temp1 &= ~temp2;
377         temp2 = (uint32_t)channel << (5 * (rank - 1));
378         temp1 |= temp2;
379         adc->REGSEQ3 = temp1;
380     }
381     else if (rank < 13)
382     {
383         temp1 = adc->REGSEQ2;
384         temp2 = (uint32_t)0x1F << (5 * (rank - 7));
385         temp1 &= ~temp2;
386         temp2 = (uint32_t)channel << (5 * (rank - 7));
387         temp1 |= temp2;
388         adc->REGSEQ2 = temp1;
389     }
390     else
391     {
392         temp1 = adc->REGSEQ1;
393         temp2 = (uint32_t)0x1F << (5 * (rank - 13));
394         temp1 &= ~temp2;
395         temp2 = (uint32_t)channel << (5 * (rank - 13));
396         temp1 |= temp2;
397         adc->REGSEQ1 = temp1;
398     }
399 }
400 
401 /*!
402  * @brief     Enables the selected ADC software start conversion of the regular channels.
403  *
404  * @param     adc: Select ADCx where x can be 1, 2 or 3.
405  *
406  * @retval    None
407  */
ADC_SoftwareStartConv(ADC_T * adc)408 void ADC_SoftwareStartConv(ADC_T *adc)
409 {
410     adc->CTRL2_B.REGCHSC = BIT_SET;
411 }
412 
413 /*!
414  * @brief     Reads the selected ADC Software start regular conversion Status.
415  *
416  * @param     adc: Select ADCx where x can be 1, 2 or 3.
417  *
418  * @retval    The new state of ADC software start conversion (SET or RESET).
419  */
ADC_ReadSoftwareStartConvStatus(ADC_T * adc)420 uint8_t ADC_ReadSoftwareStartConvStatus(ADC_T *adc)
421 {
422     return (uint8_t)adc->CTRL2_B.REGCHSC;
423 }
424 
425 /**
426  * @brief     Enables the EOC on each regular channel conversion
427  *
428  * @param     adc: Select ADCx where x can be 1, 2 or 3.
429  *
430  * @retval    None
431  */
ADC_EnableEOCOnEachChannel(ADC_T * adc)432 void ADC_EnableEOCOnEachChannel(ADC_T *adc)
433 {
434     adc->CTRL2_B.EOCSEL = BIT_SET;
435 
436 }
437 
438 /**
439  * @brief     Disables the EOC on each regular channel conversion
440  *
441  * @param     adc: Select ADCx where x can be 1, 2 or 3.
442  *
443  * @retval    None
444  */
ADC_DisableEOCOnEachChannel(ADC_T * adc)445 void ADC_DisableEOCOnEachChannel(ADC_T *adc)
446 {
447     adc->CTRL2_B.EOCSEL = BIT_RESET;
448 }
449 
450 /*!
451  * @brief     Enables the ADC continuous conversion mode
452  *
453  * @param     adc: Select ADCx where x can be 1, 2 or 3.
454  *
455  * @retval    None
456  */
ADC_EnableContinuousMode(ADC_T * adc)457 void ADC_EnableContinuousMode(ADC_T *adc)
458 {
459     adc->CTRL2_B.CONTCEN = BIT_SET;
460 }
461 
462 /*!
463  * @brief     Disables the ADC continuous conversion mode
464  *
465  * @param     adc: Select ADCx where x can be 1, 2 or 3.
466  *
467  * @retval    None
468  */
ADC_DisableContinuousMode(ADC_T * adc)469 void ADC_DisableContinuousMode(ADC_T *adc)
470 {
471     adc->CTRL2_B.CONTCEN = BIT_RESET;;
472 }
473 
474 /*!
475  * @brief     Configures the discontinuous mode for the selected ADC regular group
476  *            channel.
477  *
478  * @param     adc: Select ADCx where x can be 1, 2 or 3.
479  *
480  * @param     number: specifies the discontinuous mode regular channel count value.
481  *                    This number must be between 1 and 8.
482  *
483  * @retval    None
484  */
ADC_ConfigDiscMode(ADC_T * adc,uint8_t number)485 void ADC_ConfigDiscMode(ADC_T *adc, uint8_t number)
486 {
487     adc->CTRL1_B.DISCNUMCFG = number - 1;
488 }
489 
490 /*!
491  * @brief     Enables the discontinuous mode on regular group channel.
492  *
493  * @param     adc: Select ADCx where x can be 1, 2 or 3.
494  *
495  * @retval    None
496  */
ADC_EnableDiscMode(ADC_T * adc)497 void ADC_EnableDiscMode(ADC_T *adc)
498 {
499     adc->CTRL1_B.REGDISCEN = BIT_SET;
500 }
501 
502 /*!
503  * @brief     Disables the discontinuous mode for injected group channel.
504  *
505  * @param     adc: Select ADCx where x can be 1, 2 or 3.
506  *
507  * @retval    None
508  */
ADC_DisableDiscMode(ADC_T * adc)509 void ADC_DisableDiscMode(ADC_T *adc)
510 {
511     adc->CTRL1_B.REGDISCEN = BIT_RESET;
512 }
513 
514 /*!
515  * @brief     Reads the specified ADC conversion result data.
516  *
517  * @param     adc: Select ADCx where x can be 1, 2 or 3.
518  *
519  * @retval    The Data conversion value.
520  */
ADC_ReadConversionValue(ADC_T * adc)521 uint16_t ADC_ReadConversionValue(ADC_T *adc)
522 {
523     return (uint16_t) adc->REGDATA;
524 }
525 
526 /*!
527  * @brief     Reads the specified ADC conversion result data in dual mode.
528  *
529  * @param     adc: Select ADCx where x can be 1, 2 or 3.
530  *
531  * @retval    The Data conversion value.
532  *            - In dual mode:
533  *                Data[15:0] contain the regular data of ADC1.
534  *                Data[31:16] contain the regular data of ADC2.
535  *            - In triple mode:
536  *                Data[15:0] contain alternatively the regular data of ADC1, ADC3 and ADC2.
537  *                Data[31:16] contain alternatively the regular data of ADC2, ADC1 and ADC3.
538  */
ADC_ReadMultiValue(void)539 uint32_t ADC_ReadMultiValue(void)
540 {
541     return ADC->CDATA;
542 }
543 
544 /*!
545  * @brief     Enables the specified ADC DMA request.
546  *
547  * @param     adc: Select ADCx where x can be 1, 2 or 3.
548  *
549  * @retval    The Data conversion value.
550  */
ADC_EnableDMA(ADC_T * adc)551 void ADC_EnableDMA(ADC_T *adc)
552 {
553     adc->CTRL2_B.DMAEN = BIT_SET;
554 }
555 
556 /*!
557  * @brief     Disables the specified ADC DMA request.
558  *
559  * @param     adc: Select ADCx where x can be 1, 2 or 3.
560  *
561  * @retval    The Data conversion value.
562  */
ADC_DisableDMA(ADC_T * adc)563 void ADC_DisableDMA(ADC_T *adc)
564 {
565     adc->CTRL2_B.DMAEN = BIT_RESET;
566 }
567 /*!
568  * @brief     Enables  the ADC DMA request after last transfer (Single-ADC mode)
569  *
570  * @param     adc: Select ADCx where x can be 1, 2 or 3.
571  *
572  * @retval    The Data conversion value.
573  */
ADC_EnableDMARequest(ADC_T * adc)574 void ADC_EnableDMARequest(ADC_T *adc)
575 {
576     adc->CTRL2_B.DMADISSEL = BIT_SET;
577 }
578 /*!
579  * @brief     Disables  the ADC DMA request after last transfer (Single-ADC mode)
580  *
581  * @param     adc: Select ADCx where x can be 1, 2 or 3.
582  *
583  * @retval    The Data conversion value.
584  */
ADC_DisableDMARequest(ADC_T * adc)585 void ADC_DisableDMARequest(ADC_T *adc)
586 {
587     adc->CTRL2_B.DMADISSEL = BIT_RESET;
588 }
589 
590 /*!
591  * @brief     Enables the ADC DMA request after last transfer in multi ADC mode
592  *
593  * @param     None
594  *
595  * @retval    None
596  */
ADC_EnableMultiModeDMARequest(void)597 void ADC_EnableMultiModeDMARequest(void)
598 {
599     ADC->CCTRL_B.DMADISSEL = BIT_SET;
600 }
601 
602 /*!
603  * @brief     Disables the ADC DMA request after last transfer in multi ADC mode
604  *
605  * @param     None
606  *
607  * @retval    None
608  */
ADC_DisableMultiModeDMARequest(void)609 void ADC_DisableMultiModeDMARequest(void)
610 {
611     ADC->CCTRL_B.DMADISSEL = BIT_RESET;
612 }
613 
614 /*!
615  * @brief     Configures the specified ADC injected channel.
616  *
617  * @param     adc: Select ADCx where x can be 1, 2 or 3.
618  *
619  * @param     channel: the ADC channel to configure.
620  *                    This parameter can be one of the following values:
621  *                    @arg ADC_CHANNEL_0:  ADC channel 0
622  *                    @arg ADC_CHANNEL_1:  ADC channel 1
623  *                    @arg ADC_CHANNEL_2:  ADC channel 2
624  *                    @arg ADC_CHANNEL_3:  ADC channel 3
625  *                    @arg ADC_CHANNEL_4:  ADC channel 4
626  *                    @arg ADC_CHANNEL_5:  ADC channel 5
627  *                    @arg ADC_CHANNEL_6:  ADC channel 6
628  *                    @arg ADC_CHANNEL_7:  ADC channel 7
629  *                    @arg ADC_CHANNEL_8:  ADC channel 8
630  *                    @arg ADC_CHANNEL_9:  ADC channel 9
631  *                    @arg ADC_CHANNEL_10: ADC channel 10
632  *                    @arg ADC_CHANNEL_11: ADC channel 11
633  *                    @arg ADC_CHANNEL_12: ADC channel 12
634  *                    @arg ADC_CHANNEL_13: ADC channel 13
635  *                    @arg ADC_CHANNEL_14: ADC channel 14
636  *                    @arg ADC_CHANNEL_15: ADC channel 15
637  *                    @arg ADC_CHANNEL_16: ADC channel 16
638  *                    @arg ADC_CHANNEL_17: ADC channel 17
639  *                    @arg ADC_CHANNEL_18: ADC Channel 18
640  *
641  * @param     rank: The rank in the regular group sequencer
642  *                     This parameter must be between 1 to 16.
643  *
644  * @param     sampleTime: the specified ADC channel SampleTime
645  *                     The parameter can be one of following values:
646  *                     @arg ADC_SAMPLETIME_3CYCLES:   Sample time equal to 3 cycles
647  *                     @arg ADC_SAMPLETIME_15CYCLES:  Sample time equal to 15 cycles
648  *                     @arg ADC_SAMPLETIME_28CYCLES:  Sample time equal to 28 cycles
649  *                     @arg ADC_SAMPLETIME_56CYCLES:  Sample time equal to 56 cycles
650  *                     @arg ADC_SAMPLETIME_84CYCLES:  Sample time equal to 84 cycles
651  *                     @arg ADC_SAMPLETIME_112CYCLES: Sample time equal to 112 cycles
652  *                     @arg ADC_SAMPLETIME_144CYCLES: Sample time equal to 144 cycles
653  *                     @arg ADC_SAMPLETIME_480CYCLES: Sample time equal to 480 cycles
654  *
655  * @retval    None
656  */
657 
ADC_ConfigInjectedChannel(ADC_T * adc,uint8_t channel,uint8_t rank,uint8_t sampleTime)658 void ADC_ConfigInjectedChannel(ADC_T *adc, uint8_t channel, uint8_t rank, uint8_t sampleTime)
659 {
660     uint32_t temp1 = 0;
661     uint32_t temp2 = 0;
662 
663     if (channel > ADC_CHANNEL_9)
664     {
665         temp1 = adc->SMPTIM1;
666         temp2 = (uint32_t)7 << (3 * (channel - 10));
667         temp1 &= ~temp2;
668         temp2 = (uint32_t)sampleTime << (3 * (channel - 10));
669         temp1 |= temp2;
670         adc->SMPTIM1 = temp1;
671     }
672     else
673     {
674         temp1 = adc->SMPTIM2;
675         temp2 = (uint32_t)7 << (3 * channel);
676         temp1 &= ~temp2;
677         temp2 = (uint32_t)sampleTime << (3 * channel);
678         temp1 |= temp2;
679         adc->SMPTIM2 = temp1;
680     }
681 
682     temp1 = adc->INJSEQ;
683     temp2 = (uint32_t)0x1F << (5 * ((rank + 3) - (adc->INJSEQ_B.INJSEQLEN + 1)));
684     temp1 &= ~temp2;
685     temp2 = (uint32_t)channel << (5 * ((rank + 3) - (adc->INJSEQ_B.INJSEQLEN + 1)));
686     temp1 |= temp2;
687     adc->INJSEQ = temp1;
688 }
689 
690 /*!
691  * @brief     Configures the sequencer length for injected channels
692  *
693  * @param     adc: Select ADCx where x can be 1, 2 or 3.
694  *
695  * @param     length: The sequencer length.
696  *                    This parameter must be a number between 1 to 4.
697  *
698  * @retval    None
699  */
ADC_ConfigInjectedSequencerLength(ADC_T * adc,uint8_t length)700 void ADC_ConfigInjectedSequencerLength(ADC_T *adc, uint8_t length)
701 {
702     adc->INJSEQ_B.INJSEQLEN = length - 1;
703 }
704 
705 /*!
706  * @brief     Configures the specified ADC injected channel conversion value offset.
707  *
708  * @param     adc: Select ADCx where x can be 1, 2 or 3.
709  *
710  * @param     channel: Select the ADC injected channel.
711  *                     This parameter can be one of the following values:
712  *                     @arg ADC_INJEC_CHANNEL_1: select Injected Channel 1
713  *                     @arg ADC_INJEC_CHANNEL_2: select Injected Channel 2
714  *                     @arg ADC_INJEC_CHANNEL_3: select Injected Channel 3
715  *                     @arg ADC_INJEC_CHANNEL_4: select Injected Channel 4
716  *
717  * @param     offset: The specified ADC injected channel offset.
718  *                    This parameter must be a 12bit value.
719  *
720  * @retval    None
721  */
ADC_ConfigInjectedOffset(ADC_T * adc,ADC_INJEC_CHANNEL_T channel,uint16_t offset)722 void ADC_ConfigInjectedOffset(ADC_T *adc, ADC_INJEC_CHANNEL_T channel, uint16_t offset)
723 {
724     switch ((uint8_t)channel)
725     {
726     case 0x01:
727         adc->INJDOF1_B.INJDOF1 = offset;
728         break;
729     case 0x02:
730         adc->INJDOF2_B.INJDOF2 = offset;
731         break;
732     case 0x03:
733         adc->INJDOF3_B.INJDOF3 = offset;
734         break;
735     case 0x04:
736         adc->INJDOF4_B.INJDOF4 = offset;
737         break;
738     default :
739         break;
740     }
741 }
742 
743 /*!
744  * @brief     Configures the specified ADC external trigger for injected channels conversion
745  *
746  * @param     adc: Select ADCx where x can be 1, 2 or 3.
747  *
748  * @param     extTrigInjecConv: Select the ADC trigger to start injected conversion
749  *                 This parameter can be one of the following values:
750  *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR1_CC4:  Timer1 capture compare4 selected
751  *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR1_TRGO: Timer1 TRGO event selected
752  *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR2_CC1:  Timer2 capture compare1 selected
753  *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR2_TRGO: Timer2 TRGO event selected
754  *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR3_CC2:  Timer3 capture compare2 selected
755  *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR3_CC4:  Timer3 capture compare4 selected
756  *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR4_CC1:  Timer4 capture compare1 selected
757  *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR4_CC2:  Timer4 capture compare2 selected
758  *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR4_CC3:  Timer4 capture compare3 selected
759  *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR4_TRGO: Timer4 TRGO event selected
760  *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR5_CC4:  Timer5 capture compare4 selected
761  *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR5_TRGO: Timer5 TRGO event selected
762  *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR8_CC2:  Timer8 capture compare2 selected
763  *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR8_CC3:  Timer8 capture compare3 selected
764  *                 @arg ADC_EXT_TRIG_INJEC_CONV_TMR8_CC4:  Timer8 capture compare4 selected
765  *                 @arg ADC_EXT_TRIG_INJEC_CONV_EINT15: External interrupt line 15 event selected
766  *
767  * @retval    None
768  */
ADC_ConfigExternalTrigInjectedConv(ADC_T * adc,ADC_EXT_TRIG_INJEC_CONV_T extTrigInjecConv)769 void ADC_ConfigExternalTrigInjectedConv(ADC_T *adc, ADC_EXT_TRIG_INJEC_CONV_T extTrigInjecConv)
770 {
771     adc->CTRL2_B.INJGEXTTRGSEL = extTrigInjecConv;
772 }
773 /*!
774  * @brief     Configures the ADCx external trigger edge for injected channels conversion.
775  *
776  * @param     adc: Select ADCx where x can be 1, 2 or 3.
777  *
778  * @param     extTrigInjecConvEdge: Select the ADC trigger to start injected conversion
779  *                 This parameter can be one of the following values:
780  *                 @arg ADC_EXT_TRIG_INJEC_EDGE_NONE          :external trigger disabled for injected conversion
781  *                 @arg ADC_EXT_TRIG_INJEC_EDGE_RISING        :detection on rising edge
782  *                 @arg ADC_EXT_TRIG_INJEC_EDGE_FALLING       :detection on falling edge
783  *                 @arg ADC_EXT_TRIG_INJEC_EDGE_RISING_FALLING:detection on both rising and falling edge
784  *
785  * @retval    None
786  */
ADC_ConfigExternalTrigInjectedConvEdge(ADC_T * adc,ADC_EXT_TRIG_INJEC_EDGE_T extTrigInjecConvEdge)787 void ADC_ConfigExternalTrigInjectedConvEdge(ADC_T *adc, ADC_EXT_TRIG_INJEC_EDGE_T extTrigInjecConvEdge)
788 {
789     adc->CTRL2_B.INJEXTTRGEN = extTrigInjecConvEdge;
790 }
791 
792 /*!
793  * @brief     Enables the selected ADC software start conversion of the injected channels.
794  *
795  * @param     adc: Select ADCx where x can be 1, 2 or 3.
796  *
797  * @retval    None
798  */
ADC_EnableSoftwareStartInjectedConv(ADC_T * adc)799 void ADC_EnableSoftwareStartInjectedConv(ADC_T *adc)
800 {
801     adc->CTRL2_B.INJCHSC = BIT_SET;
802 }
803 
804 /*!
805  * @brief     Reads the selected ADC Software start injected conversion Status.
806  *
807  * @param     adc: Select ADCx where x can be 1, 2 or 3.
808  *
809  * @retval    None
810  */
ADC_ReadSoftwareStartInjectedConvStatus(ADC_T * adc)811 uint8_t ADC_ReadSoftwareStartInjectedConvStatus(ADC_T *adc)
812 {
813     return (uint8_t)(adc->CTRL2_B.INJCHSC);
814 }
815 
816 /*!
817  * @brief     Enables the selected ADC automatic injected group conversion after regular one.
818  *
819  * @param     adc: Select ADCx where x can be 1, 2 or 3.
820  *
821  * @retval    None
822  */
ADC_EnableAutoInjectedConv(ADC_T * adc)823 void ADC_EnableAutoInjectedConv(ADC_T *adc)
824 {
825     adc->CTRL1_B.INJGACEN = BIT_SET;
826 }
827 
828 /*!
829  * @brief     Disables the selected ADC automatic injected group conversion after regular one.
830  *
831  * @param     adc: Select ADCx where x can be 1, 2 or 3.
832  *
833  * @retval    None
834  */
ADC_DisableAutoInjectedConv(ADC_T * adc)835 void ADC_DisableAutoInjectedConv(ADC_T *adc)
836 {
837     adc->CTRL1_B.INJGACEN = BIT_RESET;
838 }
839 
840 /*!
841  * @brief     Enable the specified ADC discontinuous mode for injected group.
842  *
843  * @param     adc: Select ADCx where x can be 1, 2 or 3.
844  *
845  * @retval    None
846  */
ADC_EnableInjectedDiscMode(ADC_T * adc)847 void ADC_EnableInjectedDiscMode(ADC_T *adc)
848 {
849     adc->CTRL1_B.INJDISCEN = BIT_SET;
850 }
851 
852 /*!
853  * @brief     Disable the specified ADC discontinuous mode for injected group.
854  *
855  * @param     adc: Select ADCx where x can be 1, 2 or 3.
856  *
857  * @retval    None
858  */
ADC_DisableInjectedDiscMode(ADC_T * adc)859 void ADC_DisableInjectedDiscMode(ADC_T *adc)
860 {
861     adc->CTRL1_B.INJDISCEN = BIT_RESET;
862 }
863 
864 /*!
865  * @brief     Reads the ADC injected channel conversion result
866  *
867  * @param     adc: Select ADCx where x can be 1, 2 or 3.
868  *
869  * @param     channel: the converted ADC injected channel.
870  *               This parameter can be one of the following values:
871  *               @arg ADC_INJEC_CHANNEL_1: Injected Channel1 selected
872  *               @arg ADC_INJEC_CHANNEL_2: Injected Channel2 selected
873  *               @arg ADC_INJEC_CHANNEL_3: Injected Channel3 selected
874  *               @arg ADC_INJEC_CHANNEL_4: Injected Channel4 selected
875  *
876  * @retval    The Data conversion value.
877  */
ADC_ReadInjectedConversionValue(ADC_T * adc,ADC_INJEC_CHANNEL_T channel)878 uint16_t ADC_ReadInjectedConversionValue(ADC_T *adc, ADC_INJEC_CHANNEL_T channel)
879 {
880     switch ((uint8_t)channel)
881     {
882     case 0x01:
883         return (uint16_t)adc->INJDATA1_B.INJDATA;
884     case 0x02:
885         return (uint16_t)adc->INJDATA2_B.INJDATA;
886     case 0x03:
887         return (uint16_t)adc->INJDATA3_B.INJDATA;
888     case 0x04:
889         return (uint16_t)adc->INJDATA4_B.INJDATA;
890     default :
891         return 0;
892     }
893 }
894 
895 /*!
896  * @brief     Enable the specified ADC interrupt.
897  *
898  * @param     adc: Select ADCx where x can be 1, 2 or 3.
899  *
900  * @param     interrupt: Select the ADC interrupt sources
901  *                       This parameter can be any combination of the following values:
902  *                       @arg ADC_INT_EOC: End of conversion interrupt mask
903  *                       @arg ADC_INT_AWD: Analog watchdog interrupt mask
904  *                       @arg ADC_INT_INJEOC: End of injected conversion interrupt mask
905  *                       @arg ADC_INT_OVR: Overrun interrupt enable
906  *
907  * @retval    None
908  */
ADC_EnableInterrupt(ADC_T * adc,uint32_t interrupt)909 void ADC_EnableInterrupt(ADC_T *adc, uint32_t interrupt)
910 {
911     adc->CTRL1 |= interrupt;
912 }
913 
914 /*!
915  * @brief     Disables the specified ADC interrupt.
916  *
917  * @param     adc: Select ADCx where x can be 1, 2 or 3.
918  *
919  * @param     interrupt: Select the ADC interrupt sources
920  *                       This parameter can be any combination of the following values:
921  *                       @arg ADC_INT_EOC: End of conversion interrupt mask
922  *                       @arg ADC_INT_AWD: Analog watchdog interrupt mask
923  *                       @arg ADC_INT_INJEOC: End of injected conversion interrupt mask
924  *                       @arg ADC_INT_OVR: Overrun interrupt enable
925  *
926  * @retval    None
927  */
ADC_DisableInterrupt(ADC_T * adc,uint32_t interrupt)928 void ADC_DisableInterrupt(ADC_T *adc, uint32_t interrupt)
929 {
930     adc->CTRL1 &= (uint32_t)~interrupt;
931 }
932 
933 /*!
934  * @brief     Reads the pending ADC flag
935  *
936  * @param     adc: Select ADCx where x can be 1, 2 or 3.
937  *
938  * @param     flag: Select the flag to check
939  *                  This parameter can be one of the following values:
940  *                  @arg ADC_FLAG_AWD: Analog watchdog flag
941  *                  @arg ADC_FLAG_EOC: End of conversion flag
942  *                  @arg ADC_FLAG_INJEOC: End of injected group conversion flag
943  *                  @arg ADC_FLAG_INJCS: Start of injected group conversion flag
944  *                  @arg ADC_FLAG_REGCS: Start of regular group conversion flag
945  *                  @arg ADC_FLAG_OVR: Overrun flag
946  *
947  * @retval    SET or RESET
948  */
ADC_ReadStatusFlag(ADC_T * adc,ADC_FLAG_T flag)949 uint8_t ADC_ReadStatusFlag(ADC_T *adc, ADC_FLAG_T flag)
950 {
951     return (adc->STS & flag) ? SET : RESET;
952 }
953 
954 /*!
955  * @brief     Clears the pending ADC flag
956  *
957  * @param     adc: Select ADCx where x can be 1, 2 or 3.
958  *
959  * @param     flag: Select the flag to check
960  *                  This parameter can be one of the following values:
961  *                  @arg ADC_FLAG_AWD: Analog watchdog flag
962  *                  @arg ADC_FLAG_EOC: End of conversion flag
963  *                  @arg ADC_FLAG_INJEOC: End of injected group conversion flag
964  *                  @arg ADC_FLAG_INJCS: Start of injected group conversion flag
965  *                  @arg ADC_FLAG_REGCS: Start of regular group conversion flag
966  *                  @arg ADC_FLAG_OVR: Overrun flag
967  *
968  * @retval    None
969  */
ADC_ClearStatusFlag(ADC_T * adc,uint32_t flag)970 void ADC_ClearStatusFlag(ADC_T *adc, uint32_t flag)
971 {
972     adc->STS = ~(uint32_t)flag;
973 }
974 
975 /*!
976  * @brief     Reads the specified ADC Interrupt flag.
977  *
978  * @param     adc: Select ADCx where x can be 1, 2 or 3.
979  *
980  * @param     flag: Select the ADC interrupt source.
981  *                  This parameter can be one of the following values:
982  *                  @arg ADC_INT_FLAG_EOC: End of conversion interrupt flag
983  *                  @arg ADC_INT_FLAG_AWD: Analog watchdog interrupt flag
984  *                  @arg ADC_INT_FLAG_INJEOC: End of injected conversion interrupt flag
985  *                  @arg ADC_INT_FLAG_OVR: Overrun interrupt flag
986  *
987  * @retval    SET or RESET
988  */
ADC_ReadIntFlag(ADC_T * adc,ADC_INT_FLAG_T flag)989 uint16_t ADC_ReadIntFlag(ADC_T *adc, ADC_INT_FLAG_T flag)
990 {
991     uint32_t itmask = 0;
992     uint32_t intStatus = 0;
993 
994     itmask = (uint32_t)1 << (flag >> 8);
995     intStatus = adc->CTRL1 & itmask;
996 
997     if (((adc->STS & (uint32_t)(flag & 0x3F)) != (uint32_t)RESET) && intStatus)
998     {
999         return SET;
1000     }
1001     else
1002     {
1003         return RESET;
1004     }
1005 }
1006 
1007 /*!
1008  * @brief     Clears the specified ADC Interrupt pending bits.
1009  *
1010  * @param     adc: Select ADCx where x can be 1, 2 or 3.
1011  *
1012  * @param     flag: Select the ADC interrupt source.
1013  *                  This parameter can be any combination of the following values:
1014  *                  @arg ADC_INT_FLAG_EOC: End of conversion interrupt flag
1015  *                  @arg ADC_INT_FLAG_AWD: Analog watchdog interrupt flag
1016  *                  @arg ADC_INT_FLAG_INJEOC: End of injected conversion interrupt flag
1017  *                  @arg ADC_INT_FLAG_OVR: Overrun interrupt flag
1018  *
1019  * @retval    None
1020  */
ADC_ClearIntFlag(ADC_T * adc,uint32_t flag)1021 void ADC_ClearIntFlag(ADC_T *adc, uint32_t flag)
1022 {
1023     adc->STS = ~(uint32_t)(flag & 0x3F);
1024 }
1025 
1026 /**@} end of group ADC_Functions */
1027 /**@} end of group ADC_Driver */
1028 /**@} end of group APM32F4xx_StdPeriphDriver */
1029