1 /*!
2 * @file apm32f0xx_dac.c
3 *
4 * @brief This file contains all the functions for the DAC peripheral
5 *
6 * @note It's only for APM32F051,APM32F072,APM32F091 devices
7 *
8 * @version V1.0.3
9 *
10 * @date 2022-09-20
11 *
12 * @attention
13 *
14 * Copyright (C) 2020-2022 Geehy Semiconductor
15 *
16 * You may not use this file except in compliance with the
17 * GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
18 *
19 * The program is only for reference, which is distributed in the hope
20 * that it will be useful and instructional for customers to develop
21 * their software. Unless required by applicable law or agreed to in
22 * writing, the program is distributed on an "AS IS" BASIS, WITHOUT
23 * ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
24 * See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
25 * and limitations under the License.
26 */
27
28 /* Includes */
29 #include "apm32f0xx_dac.h"
30 #include "apm32f0xx_rcm.h"
31
32 /** @addtogroup APM32F0xx_StdPeriphDriver
33 @{
34 */
35
36 /** @addtogroup DAC_Driver
37 @{
38 */
39
40 /** @defgroup DAC_Macros Macros
41 @{
42 */
43
44 /**@} end of group DAC_Macros */
45
46 /** @defgroup DAC_Enumerations Enumerations
47 @{
48 */
49
50 /**@} end of group DAC_Enumerations */
51
52 /** @defgroup DAC_Structures Structures
53 @{
54 */
55
56 /**@} end of group DAC_Structures */
57
58 /** @defgroup DAC_Variables Variables
59 @{
60 */
61
62 /**@} end of group DAC_Variables */
63
64 /** @defgroup DAC_Functions Functions
65 @{
66 */
67
68 /*!
69 * @brief Resets the DAC peripheral registers to their default reset values.
70 *
71 * @param None
72 *
73 * @retval None
74 */
DAC_Reset(void)75 void DAC_Reset(void)
76 {
77 RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_DAC);
78 RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_DAC);
79 }
80
81 /*!
82 * @brief Initializes the DAC peripheral according to the specified parameters in the dacConfig.
83 *
84 * @param channel: the selected DAC channel.
85 * This parameter can be:
86 * @arg DAC_Channel_1: DAC Channel1 selected
87 * @arg DAC_Channel_2: DAC Channel2 selected
88 *
89 * @param dacConfig: pointer to a DAC_Config_T structure that contains
90 * the configuration information for the specified DAC channel.
91 *
92 * @retval None
93 *
94 * @note DAC_Channel_2 is only for APM32F072 and APM32F091 devices
95 */
DAC_Config(uint32_t channel,DAC_Config_T * dacConfig)96 void DAC_Config(uint32_t channel, DAC_Config_T* dacConfig)
97 {
98 uint32_t tmp1 = 0, tmp2 = 0;
99
100 tmp1 = DAC->CTRL;
101
102 tmp1 &= ~(((uint32_t)0x00000FFE) << channel);
103
104 tmp2 = ((uint32_t)dacConfig->trigger | \
105 (uint32_t)dacConfig->waveGeneration | \
106 (uint32_t)dacConfig->maskAmplitudeSelect | \
107 (uint32_t)dacConfig->outputBuff);
108
109 tmp1 |= tmp2 << channel;
110
111 DAC->CTRL = tmp1;
112 }
113
114 /*!
115 * @brief Fills each DAC_InitStruct member with its default value.
116 *
117 * @param dacConfig: pointer to a DAC_InitTypeDef structure which will
118 * be configed.
119 *
120 * @retval None
121 */
DAC_ConfigStructInit(DAC_Config_T * dacConfig)122 void DAC_ConfigStructInit(DAC_Config_T* dacConfig)
123 {
124 dacConfig->trigger = DAC_TRIGGER_NONE;
125 dacConfig->waveGeneration = DAC_WAVE_GENERATION_NONE;
126 dacConfig->maskAmplitudeSelect = DAC_LFSRUNAMASK_BIT0;
127 dacConfig->outputBuff = DAC_OUTPUTBUFF_ENABLE;
128 }
129
130 /*!
131 * @brief Enables the specified DAC channel.
132 *
133 * @param channel: The selected DAC channel.
134 * This parameter can be one of the following values:
135 * @arg DAC_CHANNEL_1: DAC Channel1 selected
136 * @arg DAC_CHANNEL_2: DAC Channel2 selected
137 *
138 * @retval None
139 *
140 * @note When the DAC channel is enabled the trigger source can no more be modified.
141 *
142 * @note DAC_Channel_2 is only for APM32F072 and APM32F091 devices
143 */
DAC_Enable(DAC_CHANNEL_T channel)144 void DAC_Enable(DAC_CHANNEL_T channel)
145 {
146 if (channel == DAC_CHANNEL_1)
147 {
148 DAC->CTRL_B.ENCH1 = SET;
149 }
150 else
151 {
152 DAC->CTRL_B.ENCH2 = SET;
153 }
154 }
155
156 /*!
157 * @brief Disables the specified DAC channel.
158 *
159 * @param channel: The selected DAC channel.
160 * This parameter can be one of the following values:
161 * @arg DAC_CHANNEL_1: DAC Channel1 selected
162 * @arg DAC_CHANNEL_2: DAC Channel2 selected
163 *
164 * @retval None
165 *
166 * @note DAC_Channel_2 is only for APM32F072 and APM32F091 devices
167 */
DAC_Disable(DAC_CHANNEL_T channel)168 void DAC_Disable(DAC_CHANNEL_T channel)
169 {
170 if (channel == DAC_CHANNEL_1)
171 {
172 DAC->CTRL_B.ENCH1 = RESET;
173 }
174 else
175 {
176 DAC->CTRL_B.ENCH2 = RESET;
177 }
178 }
179
180 /*!
181 * @brief Enables the selected DAC channel software trigger.
182 *
183 * @param channel: The selected DAC channel.
184 * This parameter can be one of the following values:
185 * @arg DAC_CHANNEL_1: DAC Channel1 selected
186 * @arg DAC_CHANNEL_2: DAC Channel2 selected
187 *
188 * @retval None
189 *
190 * @note DAC_Channel_2 is only for APM32F072 and APM32F091 devices
191 */
DAC_EnableSoftwareTrigger(DAC_CHANNEL_T channel)192 void DAC_EnableSoftwareTrigger(DAC_CHANNEL_T channel)
193 {
194 if (channel == DAC_CHANNEL_1)
195 {
196 DAC->SWTRG_B.SWTRG1 = SET;
197 }
198 else
199 {
200 DAC->SWTRG_B.SWTRG2 = SET;
201 }
202 }
203
204 /*!
205 * @brief Disable the selected DAC channel software trigger.
206 *
207 * @param channel: The selected DAC channel.
208 * This parameter can be one of the following values:
209 * @arg DAC_CHANNEL_1: DAC Channel1 selected
210 * @arg DAC_CHANNEL_2: DAC Channel2 selected
211 *
212 * @retval None
213 *
214 * @note DAC_Channel_2 is only for APM32F072 and APM32F091 devices
215 */
DAC_DisableSoftwareTrigger(DAC_CHANNEL_T channel)216 void DAC_DisableSoftwareTrigger(DAC_CHANNEL_T channel)
217 {
218 if (channel == DAC_CHANNEL_1)
219 {
220 DAC->SWTRG_B.SWTRG1 = RESET;
221 }
222 else
223 {
224 DAC->SWTRG_B.SWTRG2 = RESET;
225 }
226 }
227
228 /*!
229 * @brief Enables simultaneously the two DAC channels software triggers.
230 *
231 * @param None
232 *
233 * @retval None
234 *
235 * @note This function is only for APM32F072 and APM32F091 devices
236 */
DAC_EnableDualSoftwareTrigger(void)237 void DAC_EnableDualSoftwareTrigger(void)
238 {
239 DAC->SWTRG |= DUAL_SWTRIG_SET;
240 }
241
242 /*!
243 * @brief Disables simultaneously the two DAC channels software triggers.
244 *
245 * @param None
246 *
247 * @retval None
248 *
249 * @note This function is only for APM32F072 and APM32F091 devices
250 */
DAC_DisableDualSoftwareTrigger(void)251 void DAC_DisableDualSoftwareTrigger(void)
252 {
253 DAC->SWTRG &= DUAL_SWTRIG_RESET;
254 }
255
256 /*!
257 * @brief Enables the selected DAC channel wave generation.
258 *
259 * @param channel: The selected DAC channel.
260 * This parameter can be:
261 * @arg DAC_CHANNEL_1: DAC Channel1 selected
262 * @arg DAC_CHANNEL_2: DAC Channel2 selected
263 *
264 * @param wave: specifies the wave type to enable or disable.
265 * This parameter can be:
266 * @arg DAC_WAVE_GENERATION_NOISE: noise wave generation
267 * @arg DAC_WAVE_GENERATION_TRIANGLE: triangle wave generation
268 *
269 * @retval None
270 *
271 * @note This function is only for APM32F072 and APM32F091 devices
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 |= ((uint32_t)wave) << ((uint32_t)channel);
276 }
277
278 /*!
279 * @brief Disable the selected DAC channel wave generation.
280 *
281 * @param channel: The selected DAC channel.
282 * This parameter can be:
283 * @arg DAC_CHANNEL_1: DAC Channel1 selected
284 * @arg DAC_CHANNEL_2: DAC Channel2 selected
285 *
286 * @param wave: specifies the wave type to enable or disable.
287 * This parameter can be:
288 * @arg DAC_WAVE_GENERATION_NOISE: noise wave generation
289 * @arg DAC_WAVE_GENERATION_TRIANGLE: triangle wave generation
290 *
291 * @retval None
292 *
293 * @note This function is only for APM32F072 and APM32F091 devices
294 */
DAC_DisableWaveGeneration(DAC_CHANNEL_T channel,DAC_WAVE_GENERATION_T wave)295 void DAC_DisableWaveGeneration(DAC_CHANNEL_T channel, DAC_WAVE_GENERATION_T wave)
296 {
297 DAC->CTRL &= ~((uint32_t)wave) << ((uint32_t)channel);
298 }
299
300 /*!
301 * @brief Sets the specified data holding register value for DAC channel1.
302 *
303 * @param dataAlign: Specifies the data alignment for DAC channel1.
304 * This parameter can be one of the following values:
305 * @arg DAC_ALIGN_8B_R: 8bit right data alignment selected
306 * @arg DAC_ALIGN_12B_L: 12bit left data alignment selected
307 * @arg DAC_ALIGN_12B_R: 12bit right data alignment selected
308 *
309 * @param data: Data to be loaded in the selected data holding register.
310 *
311 * @retval None
312 */
DAC_ConfigChannel1Data(DAC_DATA_ALIGN_T dataAlign,uint16_t data)313 void DAC_ConfigChannel1Data(DAC_DATA_ALIGN_T dataAlign, uint16_t data)
314 {
315 __IO uint32_t tmp = 0;
316 tmp = (uint32_t)DAC_BASE;
317 tmp += DH12RCH1_OFFSET + dataAlign;
318 *(__IO uint32_t*) tmp = data;
319 }
320
321 /*!
322 * @brief Sets the specified data holding register value for DAC channel2.
323 *
324 * @param dataAlign: Specifies the data alignment for DAC channel2.
325 * This parameter can be:
326 * @arg DAC_ALIGN_8B_R: 8bit right data alignment selected
327 * @arg DAC_ALIGN_12B_L: 12bit left data alignment selected
328 * @arg DAC_ALIGN_12B_R: 12bit right data alignment selected
329 *
330 * @param data: Data to be loaded in the selected data holding register.
331 *
332 * @retval None
333 *
334 * @note This function is only for APM32F072 and APM32F091 devices
335 */
DAC_ConfigChannel2Data(DAC_DATA_ALIGN_T dataAlign,uint16_t data)336 void DAC_ConfigChannel2Data(DAC_DATA_ALIGN_T dataAlign, uint16_t data)
337 {
338 __IO uint32_t tmp = 0;
339 tmp = (uint32_t)DAC_BASE;
340 tmp += DH12RCH2_OFFSET + dataAlign;
341 *(__IO uint32_t*)tmp = data;
342 }
343
344 /*!
345 * @brief Sets the specified data holding register value for dual channel DAC.
346 *
347 * @param dataAlign: Specifies the data alignment for dual channel DAC.
348 * This parameter can be:
349 * @arg DAC_ALIGN_8B_R: 8bit right data alignment selected
350 * @arg DAC_ALIGN_12B_L: 12bit left data alignment selected
351 * @arg DAC_ALIGN_12B_R: 12bit right data alignment selected
352 * @param data2: Data for DAC Channel2 to be loaded in the selected data holding register.
353 * @param data1: Data for DAC Channel1 to be loaded in the selected data holding register.
354 *
355 * @retval None
356 *
357 * @note In dual mode, a unique register access is required to write in both
358 * DAC channels at the same time.
359 *
360 * @note This function is only for APM32F072 and APM32F091 devices
361 */
DAC_ConfigDualChannelData(DAC_DATA_ALIGN_T dataAlign,uint16_t data2,uint16_t data1)362 void DAC_ConfigDualChannelData(DAC_DATA_ALIGN_T dataAlign, uint16_t data2, uint16_t data1)
363 {
364 uint32_t data = 0, tmp = 0;
365
366 if (dataAlign == DAC_ALIGN_8B_R)
367 {
368 data = ((uint32_t)data2 << 8) | data1;
369 }
370 else
371 {
372 data = ((uint32_t)data2 << 16) | data1;
373 }
374 tmp = (uint32_t)DAC_BASE;
375 tmp += DH12RD_OFFSET + dataAlign;
376 *(__IO uint32_t*)tmp = data;
377 }
378
379 /*!
380 * @brief Returns the last data output value of the selected DAC channel.
381 *
382 * @param channel: The selected DAC channel.
383 * This parameter can be one of the following values:
384 * @arg DAC_CHANNEL_1: DAC Channel1 selected
385 * @arg DAC_CHANNEL_2: DAC Channel2 selected
386 *
387 * @retval The selected DAC channel data output value.
388 *
389 * @note DAC_Channel_2 is only for APM32F072 and APM32F091 devices
390 */
DAC_ReadDataOutputValue(DAC_CHANNEL_T channel)391 uint16_t DAC_ReadDataOutputValue(DAC_CHANNEL_T channel)
392 {
393 uint16_t data;
394 if (channel == DAC_CHANNEL_1)
395 {
396 data = DAC->DATAOCH1_B.DATA;
397 }
398 else
399 {
400 data = DAC->DATAOCH2_B.DATA;
401 }
402 return data;
403 }
404
405 /*!
406 * @brief Enables the specified DAC channel DMA request.
407 * When enabled DMA1 is generated when an external trigger (EINT Line9,
408 * TMR2, TMR3, TMR6 or TMR15 but not a software trigger) occurs
409
410 * @param channel: the selected DAC channel.
411 * This parameter can be one of the following values:
412 * @arg DAC_CHANNEL_1: DAC Channel1 selected
413 * @arg DAC_CHANNEL_2: DAC Channel2 selected
414 *
415 * @retval None
416 *
417 * @note The DAC channel1 is mapped on DMA1 channel3 which must be already configured.
418 *
419 * @note The DAC channel2 is mapped on DMA1 channel4 which must be already configured.
420 *
421 * @note DAC_Channel_2 is only for APM32F072 and APM32F091 devices
422 */
DAC_EnableDMA(DAC_CHANNEL_T channel)423 void DAC_EnableDMA(DAC_CHANNEL_T channel)
424 {
425 if (channel == DAC_CHANNEL_1)
426 {
427 DAC->CTRL_B.DMAENCH1 = SET;
428 }
429 else
430 {
431 DAC->CTRL_B.DMAENCH2 = SET;
432 }
433 }
434
435 /*!
436 * @brief Disable the specified DAC channel DMA request.
437 *
438 * @param channel: the selected DAC channel.
439 * This parameter can be one of the following values:
440 * @arg DAC_CHANNEL_1: DAC Channel1 selected
441 * @arg DAC_CHANNEL_2: DAC Channel2 selected
442 *
443 * @retval None
444 *
445 * @note The DAC channel1 is mapped on DMA1 channel3 which must be already configured.
446 *
447 * @note The DAC channel2 is mapped on DMA1 channel4 which must be already configured.
448 *
449 * @note DAC_Channel_2 is only for APM32F072 and APM32F091 devices
450 */
DAC_DisableDMA(DAC_CHANNEL_T channel)451 void DAC_DisableDMA(DAC_CHANNEL_T channel)
452 {
453 if (channel == DAC_CHANNEL_1)
454 {
455 DAC->CTRL_B.DMAENCH1 = RESET;
456 }
457 else
458 {
459 DAC->CTRL_B.DMAENCH2 = RESET;
460 }
461 }
462
463 /*!
464 * @brief Enables the specified DAC interrupts.
465 *
466 * @param channel: The selected DAC channel.
467 * This parameter can be:
468 * @arg DAC_CHANNEL_1: DAC Channel1 selected
469 * @arg DAC_CHANNEL_2: DAC Channel2 selected
470 *
471 * @retval None
472 *
473 * @note The DMA underrun occurs when a second external trigger arrives before the
474 * acknowledgement for the first external trigger is received (first request).
475 *
476 * @note DAC_Channel_2 is only for APM32F072 and APM32F091 devices
477 */
DAC_EnableInterrupt(DAC_CHANNEL_T channel)478 void DAC_EnableInterrupt(DAC_CHANNEL_T channel)
479 {
480 if (channel == DAC_CHANNEL_1)
481 {
482 DAC->CTRL_B.DMAUDRIEN1 = SET;
483 }
484 else
485 {
486 DAC->CTRL_B.DMAUDRIEN2 = SET;
487 }
488 }
489
490 /*!
491 * @brief Disables the specified DAC interrupts.
492 *
493 * @param channel: The selected DAC channel.
494 * This parameter can be:
495 * @arg DAC_CHANNEL_1: DAC Channel1 selected
496 * @arg DAC_CHANNEL_2: DAC Channel2 selected
497 *
498 * @retval None
499 *
500 * @note The DMA underrun occurs when a second external trigger arrives before the
501 * acknowledgement for the first external trigger is received (first request).
502 *
503 * @note DAC_Channel_2 is only for APM32F072 and APM32F091 devices
504 */
DAC_DisableInterrupt(DAC_CHANNEL_T channel)505 void DAC_DisableInterrupt(DAC_CHANNEL_T channel)
506 {
507 if (channel == DAC_CHANNEL_1)
508 {
509 DAC->CTRL_B.DMAUDRIEN1 = RESET;
510 }
511 else
512 {
513 DAC->CTRL_B.DMAUDRIEN2 = RESET;
514 }
515 }
516
517 /*!
518 * @brief Reads the DAC status flag.
519 *
520 * @param flag: specifies the flag to check.
521 * This parameter can be only of the following value:
522 * @arg DAC_FLAG_CH1_DMAUDR: DMA Channel1 underrun flag
523 * @arg DAC_FLAG_CH2_DMAUDR: DMA Channel2 underrun flag, only for APM32F072 and APM32F091 devices
524 *
525 * @retval The new state of DAC flag (SET or RESET).
526 *
527 * @note The DMA underrun occurs when a second external trigger arrives before the
528 * acknowledgement for the first external trigger is received (first request).
529 */
DAC_ReadStatusFlag(DAC_FLAG_T flag)530 uint8_t DAC_ReadStatusFlag(DAC_FLAG_T flag)
531 {
532 uint16_t status;
533
534 status = (uint16_t)(DAC->STS & flag);
535 if (status == flag)
536 {
537 return SET;
538 }
539 else
540 return RESET;
541 }
542 /*!
543 * @brief Clears the DAC status flags.
544 *
545 * @param flag: specifies the flag to check.
546 * This parameter can be only of the following value:
547 * @arg DAC_FLAG_CH1_DMAUDR: DMA Channel1 underrun flag
548 * @arg DAC_FLAG_CH2_DMAUDR: DMA Channel2 underrun flag, , only for APM32F072 and APM32F091 devices
549 * @arg DAC_FLAG_DMAUDR: DMA underrun flag
550 *
551 * @retval None
552 */
DAC_ClearStatusFlag(DAC_FLAG_T flag)553 void DAC_ClearStatusFlag(DAC_FLAG_T flag)
554 {
555 DAC->STS &= (uint32_t)~flag;
556 }
557
558 /*!
559 * @brief Reads teh DAC interrupt flag.
560 *
561 * @param intFlag: specifies the DAC interrupt source to check.
562 * This parameter can be the following values:
563 * @arg DAC_INT_CH1_DMAUDR: DMA Channel1 underrun interrupt mask
564 * @arg DAC_INT_CH2_DMAUDR: DMA Channel2 underrun interrupt mask, , only for APM32F072 and APM32F091 devices
565 *
566 * @retval The new state of DAC interrupt flag (SET or RESET).
567 *
568 * @note The DMA underrun occurs when a second external trigger arrives before the
569 * acknowledgement for the first external trigger is received (first request).
570 */
DAC_ReadIntFlag(DAC_INT_T intFlag)571 uint8_t DAC_ReadIntFlag(DAC_INT_T intFlag)
572 {
573 uint32_t intEnable;
574 intEnable = (DAC->CTRL & intFlag);
575 if (((DAC->STS & intFlag) != (uint32_t)RESET) && intEnable)
576 {
577 return SET;
578 }
579 else
580 {
581 return RESET;
582 }
583 }
584
585 /*!
586 * @brief Clears the DAC channel's interrupt flag.
587 *
588 * @param intFlag: specifies the DAC interrupt pending bit to clear.
589 * This parameter can be the following values:
590 * @arg DAC_INT_CH1_DMAUDR: DMA Channel1 underrun interrupt mask
591 * @arg DAC_INT_CH2_DMAUDR: DMA Channel2 underrun interrupt mask, , only for APM32F072 and APM32F091 devices
592 *
593 * @retval None
594 */
DAC_ClearIntFlag(DAC_INT_T intFlag)595 void DAC_ClearIntFlag(DAC_INT_T intFlag)
596 {
597 DAC->STS = intFlag;
598 }
599
600 /**@} end of group DAC_Functions */
601 /**@} end of group DAC_Driver */
602 /**@} end of group APM32F0xx_StdPeriphDriver */
603