1 /*****************************************************************************
2  * Copyright (c) 2019, Nations Technologies Inc.
3  *
4  * All rights reserved.
5  * ****************************************************************************
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * - Redistributions of source code must retain the above copyright notice,
11  * this list of conditions and the disclaimer below.
12  *
13  * Nations' name may not be used to endorse or promote products derived from
14  * this software without specific prior written permission.
15  *
16  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
19  * DISCLAIMED. IN NO EVENT SHALL NATIONS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  * ****************************************************************************/
27 
28 /**
29  * @file n32wb452_dac.c
30  * @author Nations
31  * @version v1.0.1
32  *
33  * @copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved.
34  */
35 #include "n32wb452_dac.h"
36 #include "n32wb452_rcc.h"
37 
38 /** @addtogroup N32WB452_StdPeriph_Driver
39  * @{
40  */
41 
42 /** @addtogroup DAC
43  * @brief DAC driver modules
44  * @{
45  */
46 
47 /** @addtogroup DAC_Private_TypesDefinitions
48  * @{
49  */
50 
51 /**
52  * @}
53  */
54 
55 /** @addtogroup DAC_Private_Defines
56  * @{
57  */
58 
59 /* CTRL register Mask */
60 #define CTRL_CLEAR_MASK ((uint32_t)0x00000FFE)
61 
62 /* DAC Dual Channels SWTRIG masks */
63 #define DUAL_SWTRIG_SET   ((uint32_t)0x00000003)
64 #define DUAL_SWTRIG_RESET ((uint32_t)0xFFFFFFFC)
65 
66 /* DCH registers offsets */
67 #define DR12CH1_OFFSET ((uint32_t)0x00000008)
68 #define DR12CH2_OFFSET ((uint32_t)0x00000014)
69 #define DR12DCH_OFFSET ((uint32_t)0x00000020)
70 
71 /* DATO register offset */
72 #define DATO1_OFFSET ((uint32_t)0x0000002C)
73 /**
74  * @}
75  */
76 
77 /** @addtogroup DAC_Private_Macros
78  * @{
79  */
80 
81 /**
82  * @}
83  */
84 
85 /** @addtogroup DAC_Private_Variables
86  * @{
87  */
88 
89 /**
90  * @}
91  */
92 
93 /** @addtogroup DAC_Private_FunctionPrototypes
94  * @{
95  */
96 
97 /**
98  * @}
99  */
100 
101 /** @addtogroup DAC_Private_Functions
102  * @{
103  */
104 
105 /**
106  * @brief  Deinitializes the DAC peripheral registers to their default reset values.
107  */
DAC_DeInit(void)108 void DAC_DeInit(void)
109 {
110     /* Enable DAC reset state */
111     RCC_EnableAPB1PeriphReset(RCC_APB1_PERIPH_DAC, ENABLE);
112     /* Release DAC from reset state */
113     RCC_EnableAPB1PeriphReset(RCC_APB1_PERIPH_DAC, DISABLE);
114 }
115 
116 /**
117  * @brief  Initializes the DAC peripheral according to the specified
118  *         parameters in the DAC_InitStruct.
119  * @param DAC_Channel the selected DAC channel.
120  *   This parameter can be one of the following values:
121  *     @arg DAC_CHANNEL_1 DAC Channel1 selected
122  *     @arg DAC_CHANNEL_2 DAC Channel2 selected
123  * @param DAC_InitStruct pointer to a DAC_InitType structure that
124  *        contains the configuration information for the specified DAC channel.
125  */
DAC_Init(uint32_t DAC_Channel,DAC_InitType * DAC_InitStruct)126 void DAC_Init(uint32_t DAC_Channel, DAC_InitType* DAC_InitStruct)
127 {
128     uint32_t tmpreg1 = 0, tmpreg2 = 0;
129     /* Check the DAC parameters */
130     assert_param(IS_DAC_TRIGGER(DAC_InitStruct->Trigger));
131     assert_param(IS_DAC_GENERATE_WAVE(DAC_InitStruct->WaveGen));
132     assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(DAC_InitStruct->LfsrUnMaskTriAmp));
133     assert_param(IS_DAC_OUTPUT_BUFFER_STATE(DAC_InitStruct->BufferOutput));
134     /*---------------------------- DAC CTRL Configuration --------------------------*/
135     /* Get the DAC CTRL value */
136     tmpreg1 = DAC->CTRL;
137     /* Clear BOFFx, TENx, TSELx, WAVEx and MAMPx bits */
138     tmpreg1 &= ~(CTRL_CLEAR_MASK << DAC_Channel);
139     /* Configure for the selected DAC channel: buffer output, trigger, wave generation,
140        mask/amplitude for wave generation */
141     /* Set TSELx and TENx bits according to Trigger value */
142     /* Set WAVEx bits according to WaveGen value */
143     /* Set MAMPx bits according to LfsrUnMaskTriAmp value */
144     /* Set BOFFx bit according to BufferOutput value */
145     tmpreg2 = (DAC_InitStruct->Trigger | DAC_InitStruct->WaveGen | DAC_InitStruct->LfsrUnMaskTriAmp
146                | DAC_InitStruct->BufferOutput);
147     /* Calculate CTRL register value depending on DAC_Channel */
148     tmpreg1 |= tmpreg2 << DAC_Channel;
149     /* Write to DAC CTRL */
150     DAC->CTRL = tmpreg1;
151 }
152 
153 /**
154  * @brief  Fills each DAC_InitStruct member with its default value.
155  * @param DAC_InitStruct pointer to a DAC_InitType structure which will
156  *         be initialized.
157  */
DAC_ClearStruct(DAC_InitType * DAC_InitStruct)158 void DAC_ClearStruct(DAC_InitType* DAC_InitStruct)
159 {
160     /*--------------- Reset DAC init structure parameters values -----------------*/
161     /* Initialize the Trigger member */
162     DAC_InitStruct->Trigger = DAC_TRG_NONE;
163     /* Initialize the WaveGen member */
164     DAC_InitStruct->WaveGen = DAC_WAVEGEN_NONE;
165     /* Initialize the LfsrUnMaskTriAmp member */
166     DAC_InitStruct->LfsrUnMaskTriAmp = DAC_UNMASK_LFSRBIT0;
167     /* Initialize the BufferOutput member */
168     DAC_InitStruct->BufferOutput = DAC_BUFFOUTPUT_ENABLE;
169 }
170 
171 /**
172  * @brief  Enables or disables the specified DAC channel.
173  * @param DAC_Channel the selected DAC channel.
174  *   This parameter can be one of the following values:
175  *     @arg DAC_CHANNEL_1 DAC Channel1 selected
176  *     @arg DAC_CHANNEL_2 DAC Channel2 selected
177  * @param Cmd new state of the DAC channel.
178  *   This parameter can be: ENABLE or DISABLE.
179  */
DAC_Enable(uint32_t DAC_Channel,FunctionalState Cmd)180 void DAC_Enable(uint32_t DAC_Channel, FunctionalState Cmd)
181 {
182     /* Check the parameters */
183     assert_param(IS_DAC_CHANNEL(DAC_Channel));
184     assert_param(IS_FUNCTIONAL_STATE(Cmd));
185     if (Cmd != DISABLE)
186     {
187         /* Enable the selected DAC channel */
188         DAC->CTRL |= (DAC_CTRL_CH1EN << DAC_Channel);
189     }
190     else
191     {
192         /* Disable the selected DAC channel */
193         DAC->CTRL &= ~(DAC_CTRL_CH1EN << DAC_Channel);
194     }
195 }
196 
197 /**
198  * @brief  Enables or disables the specified DAC channel DMA request.
199  * @param DAC_Channel the selected DAC channel.
200  *   This parameter can be one of the following values:
201  *     @arg DAC_CHANNEL_1 DAC Channel1 selected
202  *     @arg DAC_CHANNEL_2 DAC Channel2 selected
203  * @param Cmd new state of the selected DAC channel DMA request.
204  *   This parameter can be: ENABLE or DISABLE.
205  */
DAC_DmaEnable(uint32_t DAC_Channel,FunctionalState Cmd)206 void DAC_DmaEnable(uint32_t DAC_Channel, FunctionalState Cmd)
207 {
208     /* Check the parameters */
209     assert_param(IS_DAC_CHANNEL(DAC_Channel));
210     assert_param(IS_FUNCTIONAL_STATE(Cmd));
211     if (Cmd != DISABLE)
212     {
213         /* Enable the selected DAC channel DMA request */
214         DAC->CTRL |= (DAC_CTRL_DMA1EN << DAC_Channel);
215     }
216     else
217     {
218         /* Disable the selected DAC channel DMA request */
219         DAC->CTRL &= ~(DAC_CTRL_DMA1EN << DAC_Channel);
220     }
221 }
222 
223 /**
224  * @brief  Enables or disables the selected DAC channel software trigger.
225  * @param DAC_Channel the selected DAC channel.
226  *   This parameter can be one of the following values:
227  *     @arg DAC_CHANNEL_1 DAC Channel1 selected
228  *     @arg DAC_CHANNEL_2 DAC Channel2 selected
229  * @param Cmd new state of the selected DAC channel software trigger.
230  *   This parameter can be: ENABLE or DISABLE.
231  */
DAC_SoftTrgEnable(uint32_t DAC_Channel,FunctionalState Cmd)232 void DAC_SoftTrgEnable(uint32_t DAC_Channel, FunctionalState Cmd)
233 {
234     /* Check the parameters */
235     assert_param(IS_DAC_CHANNEL(DAC_Channel));
236     assert_param(IS_FUNCTIONAL_STATE(Cmd));
237     if (Cmd != DISABLE)
238     {
239         /* Enable software trigger for the selected DAC channel */
240         DAC->SOTTR |= (uint32_t)DAC_SOTTR_TR1EN << (DAC_Channel >> 4);
241     }
242     else
243     {
244         /* Disable software trigger for the selected DAC channel */
245         DAC->SOTTR &= ~((uint32_t)DAC_SOTTR_TR1EN << (DAC_Channel >> 4));
246     }
247 }
248 
249 /**
250  * @brief  Enables or disables simultaneously the two DAC channels software
251  *   triggers.
252  * @param Cmd new state of the DAC channels software triggers.
253  *   This parameter can be: ENABLE or DISABLE.
254  */
DAC_DualSoftwareTrgEnable(FunctionalState Cmd)255 void DAC_DualSoftwareTrgEnable(FunctionalState Cmd)
256 {
257     /* Check the parameters */
258     assert_param(IS_FUNCTIONAL_STATE(Cmd));
259     if (Cmd != DISABLE)
260     {
261         /* Enable software trigger for both DAC channels */
262         DAC->SOTTR |= DUAL_SWTRIG_SET;
263     }
264     else
265     {
266         /* Disable software trigger for both DAC channels */
267         DAC->SOTTR &= DUAL_SWTRIG_RESET;
268     }
269 }
270 
271 /**
272  * @brief  Enables or disables the selected DAC channel wave generation.
273  * @param DAC_Channel the selected DAC channel.
274  *   This parameter can be one of the following values:
275  *     @arg DAC_CHANNEL_1 DAC Channel1 selected
276  *     @arg DAC_CHANNEL_2 DAC Channel2 selected
277  * @param DAC_Wave Specifies the wave type to enable or disable.
278  *   This parameter can be one of the following values:
279  *     @arg DAC_WAVE_NOISE noise wave generation
280  *     @arg DAC_WAVE_TRIANGLE triangle wave generation
281  * @param Cmd new state of the selected DAC channel wave generation.
282  *   This parameter can be: ENABLE or DISABLE.
283  */
DAC_WaveGenerationEnable(uint32_t DAC_Channel,uint32_t DAC_Wave,FunctionalState Cmd)284 void DAC_WaveGenerationEnable(uint32_t DAC_Channel, uint32_t DAC_Wave, FunctionalState Cmd)
285 {
286     /* Check the parameters */
287       __IO uint32_t tmp = 0;
288     assert_param(IS_DAC_CHANNEL(DAC_Channel));
289     assert_param(IS_DAC_WAVE(DAC_Wave));
290     assert_param(IS_FUNCTIONAL_STATE(Cmd));
291         tmp=DAC->CTRL;
292     tmp&=~(3<<(DAC_Channel+6));
293     if (Cmd != DISABLE)
294     {
295         /* Enable the selected wave generation for the selected DAC channel */
296         tmp |= DAC_Wave << DAC_Channel;
297     }
298     else
299     {
300         /* Disable the selected wave generation for the selected DAC channel */
301         tmp &=~(3<<(DAC_Channel+6));
302     }
303         DAC->CTRL = tmp;
304 }
305 
306 /**
307  * @brief  Set the specified data holding register value for DAC channel1.
308  * @param DAC_Align Specifies the data alignment for DAC channel1.
309  *   This parameter can be one of the following values:
310  *     @arg DAC_ALIGN_R_8BIT 8bit right data alignment selected
311  *     @arg DAC_ALIGN_L_12BIT 12bit left data alignment selected
312  *     @arg DAC_ALIGN_R_12BIT 12bit right data alignment selected
313  * @param Data Data to be loaded in the selected data holding register.
314  */
DAC_SetCh1Data(uint32_t DAC_Align,uint16_t Data)315 void DAC_SetCh1Data(uint32_t DAC_Align, uint16_t Data)
316 {
317     __IO uint32_t tmp = 0;
318 
319     /* Check the parameters */
320     assert_param(IS_DAC_ALIGN(DAC_Align));
321     assert_param(IS_DAC_DATA(Data));
322 
323     tmp = (uint32_t)DAC_BASE;
324     tmp += DR12CH1_OFFSET + DAC_Align;
325 
326     /* Set the DAC channel1 selected data holding register */
327     *(__IO uint32_t*)tmp = Data;
328 }
329 
330 /**
331  * @brief  Set the specified data holding register value for DAC channel2.
332  * @param DAC_Align Specifies the data alignment for DAC channel2.
333  *   This parameter can be one of the following values:
334  *     @arg DAC_ALIGN_R_8BIT 8bit right data alignment selected
335  *     @arg DAC_ALIGN_L_12BIT 12bit left data alignment selected
336  *     @arg DAC_ALIGN_R_12BIT 12bit right data alignment selected
337  * @param Data Data to be loaded in the selected data holding register.
338  */
DAC_SetCh2Data(uint32_t DAC_Align,uint16_t Data)339 void DAC_SetCh2Data(uint32_t DAC_Align, uint16_t Data)
340 {
341     __IO uint32_t tmp = 0;
342 
343     /* Check the parameters */
344     assert_param(IS_DAC_ALIGN(DAC_Align));
345     assert_param(IS_DAC_DATA(Data));
346 
347     tmp = (uint32_t)DAC_BASE;
348     tmp += DR12CH2_OFFSET + DAC_Align;
349 
350     /* Set the DAC channel2 selected data holding register */
351     *(__IO uint32_t*)tmp = Data;
352 }
353 
354 /**
355  * @brief  Set the specified data holding register value for dual channel
356  *   DAC.
357  * @param DAC_Align Specifies the data alignment for dual channel DAC.
358  *   This parameter can be one of the following values:
359  *     @arg DAC_ALIGN_R_8BIT 8bit right data alignment selected
360  *     @arg DAC_ALIGN_L_12BIT 12bit left data alignment selected
361  *     @arg DAC_ALIGN_R_12BIT 12bit right data alignment selected
362  * @param Data2 Data for DAC Channel2 to be loaded in the selected data
363  *   holding register.
364  * @param Data1 Data for DAC Channel1 to be loaded in the selected data
365  *   holding register.
366  */
DAC_SetDualChData(uint32_t DAC_Align,uint16_t Data2,uint16_t Data1)367 void DAC_SetDualChData(uint32_t DAC_Align, uint16_t Data2, uint16_t Data1)
368 {
369     uint32_t data = 0, tmp = 0;
370 
371     /* Check the parameters */
372     assert_param(IS_DAC_ALIGN(DAC_Align));
373     assert_param(IS_DAC_DATA(Data1));
374     assert_param(IS_DAC_DATA(Data2));
375 
376     /* Calculate and set dual DAC data holding register value */
377     if (DAC_Align == DAC_ALIGN_R_8BIT)
378     {
379         data = ((uint32_t)Data2 << 8) | Data1;
380     }
381     else
382     {
383         data = ((uint32_t)Data2 << 16) | Data1;
384     }
385 
386     tmp = (uint32_t)DAC_BASE;
387     tmp += DR12DCH_OFFSET + DAC_Align;
388 
389     /* Set the dual DAC selected data holding register */
390     *(__IO uint32_t*)tmp = data;
391 }
392 
393 /**
394  * @brief  Returns the last data output value of the selected DAC channel.
395  * @param DAC_Channel the selected DAC channel.
396  *   This parameter can be one of the following values:
397  *     @arg DAC_CHANNEL_1 DAC Channel1 selected
398  *     @arg DAC_CHANNEL_2 DAC Channel2 selected
399  * @return The selected DAC channel data output value.
400  */
DAC_GetOutputDataVal(uint32_t DAC_Channel)401 uint16_t DAC_GetOutputDataVal(uint32_t DAC_Channel)
402 {
403     __IO uint32_t tmp = 0;
404 
405     /* Check the parameters */
406     assert_param(IS_DAC_CHANNEL(DAC_Channel));
407 
408     tmp = (uint32_t)DAC_BASE;
409     tmp += DATO1_OFFSET + ((uint32_t)DAC_Channel >> 2);
410 
411     /* Returns the DAC channel data output register value */
412     return (uint16_t)(*(__IO uint32_t*)tmp);
413 }
414 
415 /**
416  * @}
417  */
418 
419 /**
420  * @}
421  */
422 
423 /**
424  * @}
425  */
426