1 /*!
2 \file gd32e10x_dac.c
3 \brief DAC driver
4
5 \version 2017-12-26, V1.0.0, firmware for GD32E10x
6 \version 2020-09-30, V1.1.0, firmware for GD32E10x
7 \version 2020-12-31, V1.2.0, firmware for GD32E10x
8 \version 2022-06-30, V1.3.0, firmware for GD32E10x
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 "gd32e10x_dac.h"
39
40 /* DAC register bit offset */
41 #define DAC1_REG_OFFSET ((uint32_t)16U)
42 #define DH_12BIT_OFFSET ((uint32_t)16U)
43 #define DH_8BIT_OFFSET ((uint32_t)8U)
44
45 /*!
46 \brief deinitialize DAC
47 \param[in] none
48 \param[out] none
49 \retval none
50 */
dac_deinit(void)51 void dac_deinit(void)
52 {
53 rcu_periph_reset_enable(RCU_DACRST);
54 rcu_periph_reset_disable(RCU_DACRST);
55 }
56
57 /*!
58 \brief enable DAC
59 \param[in] dac_periph
60 \arg DACx(x=0,1)
61 \param[out] none
62 \retval none
63 */
dac_enable(uint32_t dac_periph)64 void dac_enable(uint32_t dac_periph)
65 {
66 if(DAC0 == dac_periph){
67 DAC_CTL |= DAC_CTL_DEN0;
68 }else{
69 DAC_CTL |= DAC_CTL_DEN1;
70 }
71 }
72
73 /*!
74 \brief disable DAC
75 \param[in] dac_periph
76 \arg DACx(x=0,1)
77 \param[out] none
78 \retval none
79 */
dac_disable(uint32_t dac_periph)80 void dac_disable(uint32_t dac_periph)
81 {
82 if(DAC0 == dac_periph){
83 DAC_CTL &= ~DAC_CTL_DEN0;
84 }else{
85 DAC_CTL &= ~DAC_CTL_DEN1;
86 }
87 }
88
89 /*!
90 \brief enable DAC DMA function
91 \param[in] dac_periph
92 \arg DACx(x=0,1)
93 \param[out] none
94 \retval none
95 */
dac_dma_enable(uint32_t dac_periph)96 void dac_dma_enable(uint32_t dac_periph)
97 {
98 if(DAC0 == dac_periph){
99 DAC_CTL |= DAC_CTL_DDMAEN0;
100 }else{
101 DAC_CTL |= DAC_CTL_DDMAEN1;
102 }
103 }
104
105 /*!
106 \brief disable DAC DMA function
107 \param[in] dac_periph
108 \arg DACx(x=0,1)
109 \param[out] none
110 \retval none
111 */
dac_dma_disable(uint32_t dac_periph)112 void dac_dma_disable(uint32_t dac_periph)
113 {
114 if(DAC0 == dac_periph){
115 DAC_CTL &= ~DAC_CTL_DDMAEN0;
116 }else{
117 DAC_CTL &= ~DAC_CTL_DDMAEN1;
118 }
119 }
120
121 /*!
122 \brief enable DAC output buffer
123 \param[in] dac_periph
124 \arg DACx(x=0,1)
125 \param[out] none
126 \retval none
127 */
dac_output_buffer_enable(uint32_t dac_periph)128 void dac_output_buffer_enable(uint32_t dac_periph)
129 {
130 if(DAC0 == dac_periph){
131 DAC_CTL &= ~DAC_CTL_DBOFF0;
132 }else{
133 DAC_CTL &= ~DAC_CTL_DBOFF1;
134 }
135 }
136
137 /*!
138 \brief disable DAC output buffer
139 \param[in] dac_periph
140 \arg DACx(x=0,1)
141 \param[out] none
142 \retval none
143 */
dac_output_buffer_disable(uint32_t dac_periph)144 void dac_output_buffer_disable(uint32_t dac_periph)
145 {
146 if(DAC0 == dac_periph){
147 DAC_CTL |= DAC_CTL_DBOFF0;
148 }else{
149 DAC_CTL |= DAC_CTL_DBOFF1;
150 }
151 }
152
153 /*!
154 \brief get DAC output value
155 \param[in] dac_periph
156 \arg DACx(x=0,1)
157 \param[out] none
158 \retval DAC output data
159 */
dac_output_value_get(uint32_t dac_periph)160 uint16_t dac_output_value_get(uint32_t dac_periph)
161 {
162 uint16_t data = 0U;
163 if(DAC0 == dac_periph){
164 /* store the DAC0 output value */
165 data = (uint16_t)DAC0_DO;
166 }else{
167 /* store the DAC1 output value */
168 data = (uint16_t)DAC1_DO;
169 }
170 return data;
171 }
172
173 /*!
174 \brief set the DAC specified data holding register value
175 \param[in] dac_periph
176 \arg DACx(x=0,1)
177 \param[in] dac_align
178 only one parameter can be selected which is shown as below:
179 \arg DAC_ALIGN_8B_R: data right 8b alignment
180 \arg DAC_ALIGN_12B_R: data right 12b alignment
181 \arg DAC_ALIGN_12B_L: data left 12b alignment
182 \param[in] data: data to be loaded
183 \param[out] none
184 \retval none
185 */
dac_data_set(uint32_t dac_periph,uint32_t dac_align,uint16_t data)186 void dac_data_set(uint32_t dac_periph, uint32_t dac_align, uint16_t data)
187 {
188 if(DAC0 == dac_periph){
189 switch(dac_align){
190 /* data right 12b alignment */
191 case DAC_ALIGN_12B_R:
192 DAC0_R12DH = data;
193 break;
194 /* data left 12b alignment */
195 case DAC_ALIGN_12B_L:
196 DAC0_L12DH = data;
197 break;
198 /* data right 8b alignment */
199 case DAC_ALIGN_8B_R:
200 DAC0_R8DH = data;
201 break;
202 default:
203 break;
204 }
205 }else{
206 switch(dac_align){
207 /* data right 12b alignment */
208 case DAC_ALIGN_12B_R:
209 DAC1_R12DH = data;
210 break;
211 /* data left 12b alignment */
212 case DAC_ALIGN_12B_L:
213 DAC1_L12DH = data;
214 break;
215 /* data right 8b alignment */
216 case DAC_ALIGN_8B_R:
217 DAC1_R8DH = data;
218 break;
219 default:
220 break;
221 }
222 }
223 }
224
225 /*!
226 \brief enable DAC trigger
227 \param[in] dac_periph
228 \arg DACx(x=0,1)
229 \param[out] none
230 \retval none
231 */
dac_trigger_enable(uint32_t dac_periph)232 void dac_trigger_enable(uint32_t dac_periph)
233 {
234 if(DAC0 == dac_periph){
235 DAC_CTL |= DAC_CTL_DTEN0;
236 }else{
237 DAC_CTL |= DAC_CTL_DTEN1;
238 }
239 }
240
241 /*!
242 \brief disable DAC trigger
243 \param[in] dac_periph
244 \arg DACx(x=0,1)
245 \param[out] none
246 \retval none
247 */
dac_trigger_disable(uint32_t dac_periph)248 void dac_trigger_disable(uint32_t dac_periph)
249 {
250 if(DAC0 == dac_periph){
251 DAC_CTL &= ~DAC_CTL_DTEN0;
252 }else{
253 DAC_CTL &= ~DAC_CTL_DTEN1;
254 }
255 }
256
257 /*!
258 \brief set DAC trigger source
259 \param[in] dac_periph
260 \arg DACx(x=0,1)
261 \param[in] triggersource: external triggers of DAC
262 only one parameter can be selected which is shown as below:
263 \arg DAC_TRIGGER_T1_TRGO: TIMER1 TRGO
264 \arg DAC_TRIGGER_T2_TRGO: TIMER2 TRGO
265 \arg DAC_TRIGGER_T3_TRGO: TIMER3 TRGO
266 \arg DAC_TRIGGER_T4_TRGO: TIMER4 TRGO
267 \arg DAC_TRIGGER_T5_TRGO: TIMER5 TRGO
268 \arg DAC_TRIGGER_T6_TRGO: TIMER6 TRGO
269 \arg DAC_TRIGGER_EXTI_9: EXTI interrupt line9 event
270 \arg DAC_TRIGGER_SOFTWARE: software trigger
271 \param[out] none
272 \retval none
273 */
dac_trigger_source_config(uint32_t dac_periph,uint32_t triggersource)274 void dac_trigger_source_config(uint32_t dac_periph,uint32_t triggersource)
275 {
276 if(DAC0 == dac_periph){
277 /* configure DAC0 trigger source */
278 DAC_CTL &= ~DAC_CTL_DTSEL0;
279 DAC_CTL |= triggersource;
280 }else{
281 /* configure DAC1 trigger source */
282 DAC_CTL &= ~DAC_CTL_DTSEL1;
283 DAC_CTL |= (triggersource << DAC1_REG_OFFSET);
284 }
285 }
286
287 /*!
288 \brief enable DAC software trigger
289 \param[in] dac_periph
290 \arg DACx(x=0,1)
291 \retval none
292 */
dac_software_trigger_enable(uint32_t dac_periph)293 void dac_software_trigger_enable(uint32_t dac_periph)
294 {
295 if(DAC0 == dac_periph){
296 DAC_SWT |= DAC_SWT_SWTR0;
297 }else{
298 DAC_SWT |= DAC_SWT_SWTR1;
299 }
300 }
301
302 /*!
303 \brief disable DAC software trigger
304 \param[in] dac_periph
305 \arg DACx(x=0,1)
306 \param[out] none
307 \retval none
308 */
dac_software_trigger_disable(uint32_t dac_periph)309 void dac_software_trigger_disable(uint32_t dac_periph)
310 {
311 if(DAC0 == dac_periph){
312 DAC_SWT &= ~DAC_SWT_SWTR0;
313 }else{
314 DAC_SWT &= ~DAC_SWT_SWTR1;
315 }
316 }
317
318 /*!
319 \brief configure DAC wave mode
320 \param[in] dac_periph
321 \arg DACx(x=0,1)
322 \param[in] wave_mode
323 only one parameter can be selected which is shown as below:
324 \arg DAC_WAVE_DISABLE: wave disable
325 \arg DAC_WAVE_MODE_LFSR: LFSR noise mode
326 \arg DAC_WAVE_MODE_TRIANGLE: triangle noise mode
327 \param[out] none
328 \retval none
329 */
dac_wave_mode_config(uint32_t dac_periph,uint32_t wave_mode)330 void dac_wave_mode_config(uint32_t dac_periph, uint32_t wave_mode)
331 {
332 if(DAC0 == dac_periph){
333 /* configure DAC0 wave mode */
334 DAC_CTL &= ~DAC_CTL_DWM0;
335 DAC_CTL |= wave_mode;
336 }else{
337 /* configure DAC1 wave mode */
338 DAC_CTL &= ~DAC_CTL_DWM1;
339 DAC_CTL |= (wave_mode << DAC1_REG_OFFSET);
340 }
341 }
342
343 /*!
344 \brief configure DAC wave bit width
345 \param[in] dac_periph
346 \arg DACx(x=0,1)
347 \param[in] bit_width
348 only one parameter can be selected which is shown as below:
349 \arg DAC_WAVE_BIT_WIDTH_1: bit width of the wave signal is 1
350 \arg DAC_WAVE_BIT_WIDTH_2: bit width of the wave signal is 2
351 \arg DAC_WAVE_BIT_WIDTH_3: bit width of the wave signal is 3
352 \arg DAC_WAVE_BIT_WIDTH_4: bit width of the wave signal is 4
353 \arg DAC_WAVE_BIT_WIDTH_5: bit width of the wave signal is 5
354 \arg DAC_WAVE_BIT_WIDTH_6: bit width of the wave signal is 6
355 \arg DAC_WAVE_BIT_WIDTH_7: bit width of the wave signal is 7
356 \arg DAC_WAVE_BIT_WIDTH_8: bit width of the wave signal is 8
357 \arg DAC_WAVE_BIT_WIDTH_9: bit width of the wave signal is 9
358 \arg DAC_WAVE_BIT_WIDTH_10: bit width of the wave signal is 10
359 \arg DAC_WAVE_BIT_WIDTH_11: bit width of the wave signal is 11
360 \arg DAC_WAVE_BIT_WIDTH_12: bit width of the wave signal is 12
361 \param[out] none
362 \retval none
363 */
dac_wave_bit_width_config(uint32_t dac_periph,uint32_t bit_width)364 void dac_wave_bit_width_config(uint32_t dac_periph, uint32_t bit_width)
365 {
366 if(DAC0 == dac_periph){
367 /* configure DAC0 wave bit width */
368 DAC_CTL &= ~DAC_CTL_DWBW0;
369 DAC_CTL |= bit_width;
370 }else{
371 /* configure DAC1 wave bit width */
372 DAC_CTL &= ~DAC_CTL_DWBW1;
373 DAC_CTL |= (bit_width << DAC1_REG_OFFSET);
374 }
375 }
376
377 /*!
378 \brief configure DAC LFSR noise mode
379 \param[in] dac_periph
380 \arg DACx(x=0,1)
381 \param[in] unmask_bits
382 only one parameter can be selected which is shown as below:
383 \arg DAC_LFSR_BIT0: unmask the LFSR bit0
384 \arg DAC_LFSR_BITS1_0: unmask the LFSR bits[1:0]
385 \arg DAC_LFSR_BITS2_0: unmask the LFSR bits[2:0]
386 \arg DAC_LFSR_BITS3_0: unmask the LFSR bits[3:0]
387 \arg DAC_LFSR_BITS4_0: unmask the LFSR bits[4:0]
388 \arg DAC_LFSR_BITS5_0: unmask the LFSR bits[5:0]
389 \arg DAC_LFSR_BITS6_0: unmask the LFSR bits[6:0]
390 \arg DAC_LFSR_BITS7_0: unmask the LFSR bits[7:0]
391 \arg DAC_LFSR_BITS8_0: unmask the LFSR bits[8:0]
392 \arg DAC_LFSR_BITS9_0: unmask the LFSR bits[9:0]
393 \arg DAC_LFSR_BITS10_0: unmask the LFSR bits[10:0]
394 \arg DAC_LFSR_BITS11_0: unmask the LFSR bits[11:0]
395 \param[out] none
396 \retval none
397 */
dac_lfsr_noise_config(uint32_t dac_periph,uint32_t unmask_bits)398 void dac_lfsr_noise_config(uint32_t dac_periph, uint32_t unmask_bits)
399 {
400 if(DAC0 == dac_periph){
401 /* configure DAC0 LFSR noise mode */
402 DAC_CTL &= ~DAC_CTL_DWBW0;
403 DAC_CTL |= unmask_bits;
404 }else{
405 /* configure DAC1 LFSR noise mode */
406 DAC_CTL &= ~DAC_CTL_DWBW1;
407 DAC_CTL |= (unmask_bits << DAC1_REG_OFFSET);
408 }
409 }
410
411 /*!
412 \brief configure DAC triangle noise mode
413 \param[in] dac_periph
414 \arg DACx(x=0,1)
415 \param[in] amplitude
416 only one parameter can be selected which is shown as below:
417 \arg DAC_TRIANGLE_AMPLITUDE_1: triangle amplitude is 1
418 \arg DAC_TRIANGLE_AMPLITUDE_3: triangle amplitude is 3
419 \arg DAC_TRIANGLE_AMPLITUDE_7: triangle amplitude is 7
420 \arg DAC_TRIANGLE_AMPLITUDE_15: triangle amplitude is 15
421 \arg DAC_TRIANGLE_AMPLITUDE_31: triangle amplitude is 31
422 \arg DAC_TRIANGLE_AMPLITUDE_63: triangle amplitude is 63
423 \arg DAC_TRIANGLE_AMPLITUDE_127: triangle amplitude is 127
424 \arg DAC_TRIANGLE_AMPLITUDE_255: triangle amplitude is 255
425 \arg DAC_TRIANGLE_AMPLITUDE_511: triangle amplitude is 511
426 \arg DAC_TRIANGLE_AMPLITUDE_1023: triangle amplitude is 1023
427 \arg DAC_TRIANGLE_AMPLITUDE_2047: triangle amplitude is 2047
428 \arg DAC_TRIANGLE_AMPLITUDE_4095: triangle amplitude is 4095
429 \param[out] none
430 \retval none
431 */
dac_triangle_noise_config(uint32_t dac_periph,uint32_t amplitude)432 void dac_triangle_noise_config(uint32_t dac_periph, uint32_t amplitude)
433 {
434 if(DAC0 == dac_periph){
435 /* configure DAC0 triangle noise mode */
436 DAC_CTL &= ~DAC_CTL_DWBW0;
437 DAC_CTL |= amplitude;
438 }else{
439 /* configure DAC1 triangle noise mode */
440 DAC_CTL &= ~DAC_CTL_DWBW1;
441 DAC_CTL |= (amplitude << DAC1_REG_OFFSET);
442 }
443 }
444
445 /*!
446 \brief enable DAC concurrent mode
447 \param[in] none
448 \param[out] none
449 \retval none
450 */
dac_concurrent_enable(void)451 void dac_concurrent_enable(void)
452 {
453 uint32_t ctl = 0U;
454 ctl = DAC_CTL_DEN0 | DAC_CTL_DEN1;
455 DAC_CTL |= (ctl);
456 }
457
458 /*!
459 \brief disable DAC concurrent mode
460 \param[in] none
461 \param[out] none
462 \retval none
463 */
dac_concurrent_disable(void)464 void dac_concurrent_disable(void)
465 {
466 uint32_t ctl = 0U;
467 ctl = DAC_CTL_DEN0 | DAC_CTL_DEN1;
468 DAC_CTL &= (~ctl);
469 }
470
471 /*!
472 \brief enable DAC concurrent software trigger function
473 \param[in] none
474 \param[out] none
475 \retval none
476 */
dac_concurrent_software_trigger_enable(void)477 void dac_concurrent_software_trigger_enable(void)
478 {
479 uint32_t swt = 0U;
480 swt = DAC_SWT_SWTR0 | DAC_SWT_SWTR1;
481 DAC_SWT |= (swt);
482 }
483
484 /*!
485 \brief disable DAC concurrent software trigger function
486 \param[in] none
487 \param[out] none
488 \retval none
489 */
dac_concurrent_software_trigger_disable(void)490 void dac_concurrent_software_trigger_disable(void)
491 {
492 uint32_t swt = 0U;
493 swt = DAC_SWT_SWTR0 | DAC_SWT_SWTR1;
494 DAC_SWT &= (~swt);
495 }
496
497 /*!
498 \brief enable DAC concurrent buffer function
499 \param[in] none
500 \param[out] none
501 \retval none
502 */
dac_concurrent_output_buffer_enable(void)503 void dac_concurrent_output_buffer_enable(void)
504 {
505 uint32_t ctl = 0U;
506 ctl = DAC_CTL_DBOFF0 | DAC_CTL_DBOFF1;
507 DAC_CTL &= (~ctl);
508 }
509
510 /*!
511 \brief disable DAC concurrent buffer function
512 \param[in] none
513 \param[out] none
514 \retval none
515 */
dac_concurrent_output_buffer_disable(void)516 void dac_concurrent_output_buffer_disable(void)
517 {
518 uint32_t ctl = 0U;
519 ctl = DAC_CTL_DBOFF0 | DAC_CTL_DBOFF1;
520 DAC_CTL |= (ctl);
521 }
522
523 /*!
524 \brief set DAC concurrent mode data holding register value
525 \param[in] dac_align
526 only one parameter can be selected which is shown as below:
527 \arg DAC_ALIGN_8B_R: data right 8b alignment
528 \arg DAC_ALIGN_12B_R: data right 12b alignment
529 \arg DAC_ALIGN_12B_L: data left 12b alignment
530 \param[in] data0: data to be loaded
531 \param[in] data1: data to be loaded
532 \param[out] none
533 \retval none
534 */
dac_concurrent_data_set(uint32_t dac_align,uint16_t data0,uint16_t data1)535 void dac_concurrent_data_set(uint32_t dac_align, uint16_t data0, uint16_t data1)
536 {
537 uint32_t data = 0U;
538 switch(dac_align){
539 /* data right 12b alignment */
540 case DAC_ALIGN_12B_R:
541 data = ((uint32_t)data1 << DH_12BIT_OFFSET) | data0;
542 DACC_R12DH = data;
543 break;
544 /* data left 12b alignment */
545 case DAC_ALIGN_12B_L:
546 data = ((uint32_t)data1 << DH_12BIT_OFFSET) | data0;
547 DACC_L12DH = data;
548 break;
549 /* data right 8b alignment */
550 case DAC_ALIGN_8B_R:
551 data = ((uint32_t)data1 << DH_8BIT_OFFSET) | data0;
552 DACC_R8DH = data;
553 break;
554 default:
555 break;
556 }
557 }
558