1 /*!
2  * @file        apm32f4xx_dac.c
3  *
4  * @brief       This file contains all the functions prototypes for the DAC firmware library
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_dac.h"
27 #include "apm32f4xx_rcm.h"
28 
29 /** @addtogroup APM32F4xx_StdPeriphDriver
30   @{
31 */
32 
33 /** @defgroup DAC_Driver
34   * @brief DAC driver modules
35   @{
36 */
37 
38 /** @defgroup DAC_Functions
39   @{
40 */
41 
42 /*!
43  * @brief     Reset dac peripheral registers to their default reset values.
44  *
45  * @param     None
46  *
47  * @retval    None
48  */
DAC_Reset(void)49 void DAC_Reset(void)
50 {
51     RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_DAC);
52     RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_DAC);
53 }
54 
55 /*!
56  * @brief     Config the DAC peripheral according to the specified parameters in the dacConfig
57  *
58  * @param     channel: Select the DAC channel.
59  *                        This parameter can be one of the following values:
60  *                        @arg DAC_CHANNEL_1 : DAC channel 1
61  *                        @arg DAC_CHANNEL_2 : DAC channel 2
62  *
63  * @param     dacConfig: pointer to a DAC_Config_T structure
64  *
65  * @retval    None
66  */
DAC_Config(uint32_t channel,DAC_Config_T * dacConfig)67 void DAC_Config(uint32_t channel, DAC_Config_T *dacConfig)
68 {
69     uint32_t temp1 = 0, temp2 = 0;
70 
71     temp1 = DAC->CTRL;
72 
73     temp1 &= ~(((uint32_t)0x00000FFE) << channel);
74 
75     temp2 = ((uint32_t)dacConfig->trigger | \
76              (uint32_t)dacConfig->waveGeneration | \
77              (uint32_t)dacConfig->maskAmplitudeSelect | \
78              (uint32_t)dacConfig->outputBuffer);
79 
80     temp1 |= temp2 << channel;
81 
82     DAC->CTRL = temp1;
83 }
84 
85 /*!
86  * @brief     Fills each DAC_Config_T member with its default value
87  *
88  * @param     dacConfig: pointer to a DAC_Config_T structure which will be initialized
89  *
90  * @retval    None
91  */
DAC_ConfigStructInit(DAC_Config_T * dacConfig)92 void DAC_ConfigStructInit(DAC_Config_T *dacConfig)
93 {
94     dacConfig->trigger = DAC_TRIGGER_NONE;
95     dacConfig->waveGeneration = DAC_WAVE_GENERATION_NONE;
96     dacConfig->maskAmplitudeSelect = DAC_LFSR_MASK_BIT11_1;
97     dacConfig->outputBuffer = DAC_OUTPUT_BUFFER_ENBALE;
98 }
99 
100 /*!
101  * @brief     Enables the specified DAC peripheral
102  *
103  * @param     channel: Select the DAC channel.
104  *                     This parameter can be one of the following values:
105  *                        @arg DAC_CHANNEL_1 : DAC channel 1
106  *                        @arg DAC_CHANNEL_2 : DAC channel 2
107  *
108  * @retval    None
109  */
DAC_Enable(DAC_CHANNEL_T channel)110 void DAC_Enable(DAC_CHANNEL_T channel)
111 {
112     if (channel == DAC_CHANNEL_1)
113     {
114         DAC->CTRL_B.ENCH1 = BIT_SET;
115     }
116     else if (channel == DAC_CHANNEL_2)
117     {
118         DAC->CTRL_B.ENCH2 = BIT_SET;
119     }
120 }
121 
122 /*!
123  * @brief     Disables the specified DAC peripheral
124  *
125  * @param     channel: Select the DAC channel.
126  *                     This parameter can be one of the following values:
127  *                        @arg DAC_CHANNEL_1 : DAC channel 1
128  *                        @arg DAC_CHANNEL_2 : DAC channel 2
129  *
130  * @retval    None
131  */
DAC_Disable(DAC_CHANNEL_T channel)132 void DAC_Disable(DAC_CHANNEL_T channel)
133 {
134     if (channel == DAC_CHANNEL_1)
135     {
136         DAC->CTRL_B.ENCH1 = BIT_RESET;
137     }
138     else if (channel == DAC_CHANNEL_2)
139     {
140         DAC->CTRL_B.ENCH2 = BIT_RESET;
141     }
142 }
143 
144 /*!
145  * @brief     Enables the specified DAC channel DMA request
146  *
147  * @param     channel: Select the DAC channel.
148  *                        This parameter can be one of the following values:
149  *                        @arg DAC_CHANNEL_1 : DAC channel 1
150  *                        @arg DAC_CHANNEL_2 : DAC channel 2
151  *
152  * @retval    None
153  */
DAC_DMA_Enable(DAC_CHANNEL_T channel)154 void DAC_DMA_Enable(DAC_CHANNEL_T channel)
155 {
156     if (channel == DAC_CHANNEL_1)
157     {
158         DAC->CTRL_B.DMAENCH1 = BIT_SET;
159     }
160     else if (channel == DAC_CHANNEL_2)
161     {
162         DAC->CTRL_B.DMAENCH2 = BIT_SET;
163     }
164 }
165 
166 /*!
167  * @brief     Disables the specified DAC channel DMA request
168  *
169  * @param     channel: Select the DAC channel.
170  *                     This parameter can be one of the following values:
171  *                        @arg DAC_CHANNEL_1 : DAC channel 1
172  *                        @arg DAC_CHANNEL_2 : DAC channel 2
173  *
174  * @retval    None
175  */
DAC_DMA_Disable(DAC_CHANNEL_T channel)176 void DAC_DMA_Disable(DAC_CHANNEL_T channel)
177 {
178     if (channel == DAC_CHANNEL_1)
179     {
180         DAC->CTRL_B.DMAENCH1 = BIT_RESET;
181     }
182     else if (channel == DAC_CHANNEL_2)
183     {
184         DAC->CTRL_B.DMAENCH2 = BIT_RESET;
185     }
186 }
187 
188 /*!
189  * @brief     Enables the selected DAC channel software trigger
190  *
191  * @param     channel: Select the DAC channel.
192  *                     This parameter can be one of the following values:
193  *                        @arg DAC_CHANNEL_1 : DAC channel 1
194  *                        @arg DAC_CHANNEL_2 : DAC channel 2
195  *
196  * @retval    None
197  */
DAC_EnableSoftwareTrigger(DAC_CHANNEL_T channel)198 void DAC_EnableSoftwareTrigger(DAC_CHANNEL_T channel)
199 {
200     if (channel == DAC_CHANNEL_1)
201     {
202         DAC->SWTRG_B.SWTRG1 = BIT_SET;
203     }
204     else if (channel == DAC_CHANNEL_2)
205     {
206         DAC->SWTRG_B.SWTRG2 = BIT_SET;
207     }
208 }
209 
210 /*!
211  * @brief     Disable the selected DAC channel software trigger
212  *
213  * @param     channel: Select the DAC channel.
214  *                     This parameter can be one of the following values:
215  *                        @arg DAC_CHANNEL_1 : DAC channel 1
216  *                        @arg DAC_CHANNEL_2 : DAC channel 2
217  *
218  * @retval    None
219  */
DAC_DisableSoftwareTrigger(DAC_CHANNEL_T channel)220 void DAC_DisableSoftwareTrigger(DAC_CHANNEL_T channel)
221 {
222     if (channel == DAC_CHANNEL_1)
223     {
224         DAC->SWTRG_B.SWTRG1 = BIT_RESET;
225     }
226     else if (channel == DAC_CHANNEL_2)
227     {
228         DAC->SWTRG_B.SWTRG2 = BIT_RESET;
229     }
230 }
231 
232 /*!
233  * @brief     Enables simultaneously the two DAC channels software
234  *
235  * @param     None
236  *
237  * @retval    None
238  */
DAC_EnableDualSoftwareTrigger(void)239 void DAC_EnableDualSoftwareTrigger(void)
240 {
241     DAC->SWTRG_B.SWTRG1 = BIT_SET;
242     DAC->SWTRG_B.SWTRG2 = BIT_SET;
243 }
244 
245 /*!
246  * @brief     Disables simultaneously the two DAC channels software
247  *
248  * @param     None
249  *
250  * @retval    None
251  */
DAC_DisableDualSoftwareTrigger(void)252 void DAC_DisableDualSoftwareTrigger(void)
253 {
254     DAC->SWTRG_B.SWTRG1 = BIT_RESET;
255     DAC->SWTRG_B.SWTRG2 = BIT_RESET;
256 }
257 
258 /*!
259  * @brief     Enables the selected DAC channel wave generation
260  *
261  * @param     channel: Select the DAC channel.
262  *                     This parameter can be one of the following values:
263  *                     @arg DAC_CHANNEL_1 : DAC channel 1
264  *                     @arg DAC_CHANNEL_2 : DAC channel 2
265  *
266  * @param     wave: Select the wave
267  *                     This parameter can be one of the following values:
268  *                     @arg DAC_WAVE_GENERATION_NOISE    : Noise wave generation
269  *                     @arg DAC_WAVE_GENERATION_TRIANGLE : Triangle wave generation
270  *
271  * @retval    None
272  */
DAC_EnableWaveGeneration(DAC_CHANNEL_T channel,DAC_WAVE_GENERATION_T wave)273 void DAC_EnableWaveGeneration(DAC_CHANNEL_T channel, DAC_WAVE_GENERATION_T wave)
274 {
275     DAC->CTRL &= 0xFF3FFF3F;
276     DAC->CTRL |= wave << channel;
277 }
278 
279 /*!
280  * @brief     Disables the selected DAC channel wave generation
281  *
282  * @param     channel: Select the DAC channel.
283  *                     This parameter can be one of the following values:
284  *                     @arg DAC_CHANNEL_1 : DAC channel 1
285  *                     @arg DAC_CHANNEL_2 : DAC channel 2
286  *
287  * @param     wave: Select the wave
288  *                     This parameter can be one of the following values:
289  *                     @arg DAC_WAVE_GENERATION_NOISE    : Noise wave generation
290  *                     @arg DAC_WAVE_GENERATION_TRIANGLE : Triangle wave generation
291  *
292  * @retval    None
293  */
DAC_DisableWaveGeneration(DAC_CHANNEL_T channel,DAC_WAVE_GENERATION_T wave)294 void DAC_DisableWaveGeneration(DAC_CHANNEL_T channel, DAC_WAVE_GENERATION_T wave)
295 {
296     DAC->CTRL &= ~(wave << channel);
297 }
298 
299 /*!
300  * @brief     Set the specified data holding register value for DAC channel 1
301  *
302  * @param     align: DAC channel 1 data alignment
303  *                   This parameter can be one of the following values:
304  *                      @arg DAC_ALIGN_12BIT_R : 12-bit right-aligned data
305  *                      @arg DAC_ALIGN_12BIT_L : 12-bit left-aligned data
306  *                      @arg DAC_ALIGN_8BIT_R  : 8-bit right-aligned data
307  *
308  * @param     data: The data to be loaded in the selected data register.
309  *
310  * @retval    None
311  */
DAC_ConfigChannel1Data(DAC_ALIGN_T align,uint16_t data)312 void DAC_ConfigChannel1Data(DAC_ALIGN_T align, uint16_t data)
313 {
314     __IO uint32_t temp = 0;
315 
316     temp = (uint32_t)DAC_BASE;
317     temp += 0x00000008 + align;
318 
319     /* Set the DAC channel1 selected data holding register */
320     *(__IO uint32_t *) temp = data;
321 }
322 
323 /*!
324  * @brief     Set the specified data holding register value for DAC channel 2
325  *
326  * @param     align: DAC channel 2 data alignment
327  *                      This parameter can be one of the following values:
328  *                      @arg DAC_ALIGN_12BIT_R : 12-bit right-aligned data
329  *                      @arg DAC_ALIGN_12BIT_L : 12-bit left-aligned data
330  *                      @arg DAC_ALIGN_8BIT_R  : 8-bit right-aligned data
331  *
332  * @param     data: The data to be loaded in the selected data register.
333  *
334  * @retval    None
335  */
DAC_ConfigChannel2Data(DAC_ALIGN_T align,uint16_t data)336 void DAC_ConfigChannel2Data(DAC_ALIGN_T align, uint16_t data)
337 {
338     __IO uint32_t temp = 0;
339 
340     temp = (uint32_t)DAC_BASE;
341     temp += 0x00000014 + align;
342 
343     /* Set the DAC channel1 selected data holding register */
344     *(__IO uint32_t *) temp = data;
345 }
346 
347 /*!
348  * @brief     Set the specified data holding register value for dual DAC channel
349  *
350  * @param     align: Dual DAC channel data alignment
351  *                   This parameter can be one of the following values:
352  *                      @arg DAC_ALIGN_12BIT_R : 12-bit right-aligned data
353  *                      @arg DAC_ALIGN_12BIT_L : 12-bit left-aligned data
354  *                      @arg DAC_ALIGN_8BIT_R  : 8-bit right-aligned data
355  *
356  * @param     data2: Data for channel2 to be loaded in the selected data register.
357  *
358  * @param     data1: Data for channel1 to be loaded in the selected data register.
359  *
360  * @retval    None
361  */
DAC_ConfigDualChannelData(DAC_ALIGN_T align,uint16_t data2,uint16_t data1)362 void DAC_ConfigDualChannelData(DAC_ALIGN_T align, uint16_t data2, uint16_t data1)
363 {
364     uint32_t data = 0, temp = 0;
365 
366     /* Calculate and set dual DAC data holding register value */
367     if (align == DAC_ALIGN_8BIT_R)
368     {
369         data = ((uint32_t)data2 << 8) | data1;
370     }
371     else
372     {
373         data = ((uint32_t)data2 << 16) | data1;
374     }
375 
376     temp = (uint32_t)DAC_BASE;
377     temp += 0x00000020 + align;
378 
379     /* Set the dual DAC selected data holding register */
380     *(__IO uint32_t *)temp = data;
381 }
382 
383 /*!
384  * @brief     Reads the specified DAC channel data output value.
385  *
386  * @param     channel: Select the DAC channel.
387  *                     This parameter can be one of the following values:
388  *                       @arg DAC_CHANNEL_1 : DAC channel 1
389  *                       @arg DAC_CHANNEL_2 : DAC channel 2
390  *
391  * @retval    The data output value of the specified DAC channel.
392  */
DAC_ReadDataOutputValue(DAC_CHANNEL_T channel)393 uint16_t DAC_ReadDataOutputValue(DAC_CHANNEL_T channel)
394 {
395     __IO uint32_t temp = 0;
396 
397     temp = (uint32_t) DAC_BASE ;
398     temp += 0x0000002C + ((uint32_t)channel >> 2);
399 
400     /* Returns the DAC channel data output register value */
401     return (uint16_t)(*(__IO uint32_t *) temp);
402 }
403 
404 /*!
405  * @brief     Enable the specified DAC underrun interrupt.
406  *
407  * @param     channel: The selected DAC channel.
408  *                        This parameter can be one of the following values:
409  *                        @arg DAC_CHANNEL_1 : DAC channel 1
410  *                        @arg DAC_CHANNEL_2 : DAC channel 2
411  *
412  * @retval    None
413  */
DAC_EnableInterrupt(DAC_CHANNEL_T channel)414 void DAC_EnableInterrupt(DAC_CHANNEL_T channel)
415 {
416     if (channel == DAC_CHANNEL_1)
417     {
418         DAC->CTRL_B.DMAUDIEN1 = BIT_SET;
419     }
420     else if (channel == DAC_CHANNEL_2)
421     {
422         DAC->CTRL_B.DMAUDIEN2 = BIT_SET;
423     }
424 }
425 
426 /*!
427  * @brief     Disable the specified DAC underrun interrupt.
428  *
429  * @param     channel: The selected DAC channel.
430  *                     This parameter can be one of the following values:
431  *                        @arg DAC_CHANNEL_1 : DAC channel 1
432  *                        @arg DAC_CHANNEL_2 : DAC channel 2
433  *
434  * @retval    None
435  */
DAC_DisableInterrupt(DAC_CHANNEL_T channel)436 void DAC_DisableInterrupt(DAC_CHANNEL_T channel)
437 {
438     if (channel == DAC_CHANNEL_1)
439     {
440         DAC->CTRL_B.DMAUDIEN1 = BIT_RESET;
441     }
442     else if (channel == DAC_CHANNEL_2)
443     {
444         DAC->CTRL_B.DMAUDIEN2 = BIT_RESET;
445     }
446 }
447 
448 /*!
449  * @brief     Reads the specified DAC underrun flag
450  *
451  * @param     channel: The selected DAC channel.
452  *                        This parameter can be one of the following values:
453  *                        @arg DAC_CHANNEL_1 : DAC channel 1
454  *                        @arg DAC_CHANNEL_2 : DAC channel 2
455  *
456  * @retval    The new state of DAC_FLAG (SET or RESET).
457  */
DAC_ReadStatusFlag(DAC_CHANNEL_T channel)458 uint8_t DAC_ReadStatusFlag(DAC_CHANNEL_T channel)
459 {
460     if (channel == DAC_CHANNEL_1)
461     {
462         return  DAC->STS_B.DMAUDFLG1;
463     }
464     else
465     {
466         return  DAC->STS_B.DMAUDFLG2;
467     }
468 }
469 
470 /*!
471  * @brief     Clears the DAC channel's status flags.
472  *
473  * @param     channel: The selected DAC channel.
474  *                     This parameter can be one of the following values:
475  *                        @arg DAC_Channel_1: DAC Channel1 selected
476  *                        @arg DAC_Channel_2: DAC Channel2 selected
477  *
478  * @retval    None
479  */
DAC_ClearStatusFlag(DAC_CHANNEL_T channel)480 void DAC_ClearStatusFlag(DAC_CHANNEL_T channel)
481 {
482     if (channel == DAC_CHANNEL_1)
483     {
484         DAC->STS_B.DMAUDFLG1 = SET;
485     }
486     else
487     {
488         DAC->STS_B.DMAUDFLG2 = SET;
489     }
490 }
491 
492 /*!
493  * @brief     Reads the specified DAC Interrupt flag.
494  *
495  * @param     DAC_Channel: The selected DAC channel.
496  *                         This parameter can be one of the following values:
497  *                            @arg DAC_CHANNEL_1 : DAC channel 1
498  *                            @arg DAC_CHANNEL_2 : DAC channel 2
499  *
500  * @retval    The new state of DAC_IT (SET or RESET).
501  */
DAC_ReadIntFlag(DAC_CHANNEL_T channel)502 uint8_t DAC_ReadIntFlag(DAC_CHANNEL_T channel)
503 {
504     if (channel == DAC_CHANNEL_1)
505     {
506         return (DAC->CTRL_B.DMAUDIEN1 && DAC->STS_B.DMAUDFLG1);
507     }
508     else
509     {
510         return (DAC->CTRL_B.DMAUDIEN2 && DAC->STS_B.DMAUDFLG2);
511     }
512 }
513 
514 /*!
515  * @brief     Clears the DAC channel's interrupt flag.
516  *
517  * @param     channel: The selected DAC channel.
518  *                     This parameter can be one of the following values:
519  *                  @arg DAC_CHANNEL_1 : DAC channel 1
520  *                  @arg DAC_CHANNEL_2 : DAC channel 2
521  *
522  * @retval    None
523  */
DAC_ClearIntFlag(DAC_CHANNEL_T channel)524 void DAC_ClearIntFlag(DAC_CHANNEL_T channel)
525 {
526     if (channel == DAC_CHANNEL_1)
527     {
528         DAC->STS_B.DMAUDFLG1 = SET;
529     }
530     else
531     {
532         DAC->STS_B.DMAUDFLG2 = SET;
533     }
534 }
535 
536 /**@} end of group DAC_Functions */
537 /**@} end of group DAC_Driver */
538 /**@} end of group APM32F4xx_StdPeriphDriver */
539