1 /**
2   ******************************************************************************
3   * @file    stm32f7xx_hal_dac_ex.c
4   * @author  MCD Application Team
5   * @brief   Extended DAC HAL module driver.
6   *          This file provides firmware functions to manage the extended
7   *          functionalities of the DAC peripheral.
8   *
9   *
10   ******************************************************************************
11   * @attention
12   *
13   * Copyright (c) 2017 STMicroelectronics.
14   * All rights reserved.
15   *
16   * This software is licensed under terms that can be found in the LICENSE file
17   * in the root directory of this software component.
18   * If no LICENSE file comes with this software, it is provided AS-IS.
19   *
20   ******************************************************************************
21   @verbatim
22   ==============================================================================
23                       ##### How to use this driver #####
24   ==============================================================================
25     [..]
26 
27      *** Dual mode IO operation ***
28      ==============================
29      [..]
30       (+) When Dual mode is enabled (i.e. DAC Channel1 and Channel2 are used simultaneously) :
31           Use HAL_DACEx_DualGetValue() to get digital data to be converted and use
32           HAL_DACEx_DualSetValue() to set digital value to converted simultaneously in
33           Channel 1 and Channel 2.
34 
35      *** Signal generation operation ***
36      ===================================
37      [..]
38       (+) Use HAL_DACEx_TriangleWaveGenerate() to generate Triangle signal.
39       (+) Use HAL_DACEx_NoiseWaveGenerate() to generate Noise signal.
40 
41  @endverbatim
42   ******************************************************************************
43   */
44 
45 
46 /* Includes ------------------------------------------------------------------*/
47 #include "stm32f7xx_hal.h"
48 
49 /** @addtogroup STM32F7xx_HAL_Driver
50   * @{
51   */
52 
53 #ifdef HAL_DAC_MODULE_ENABLED
54 
55 #if defined(DAC)
56 
57 /** @defgroup DACEx DACEx
58   * @brief DAC Extended HAL module driver
59   * @{
60   */
61 
62 /* Private typedef -----------------------------------------------------------*/
63 /* Private define ------------------------------------------------------------*/
64 /* Private macro -------------------------------------------------------------*/
65 /* Private variables ---------------------------------------------------------*/
66 /* Private function prototypes -----------------------------------------------*/
67 /* Exported functions --------------------------------------------------------*/
68 
69 /** @defgroup DACEx_Exported_Functions DACEx Exported Functions
70   * @{
71   */
72 
73 /** @defgroup DACEx_Exported_Functions_Group2 IO operation functions
74   *  @brief    Extended IO operation functions
75   *
76 @verbatim
77   ==============================================================================
78                  ##### Extended features functions #####
79   ==============================================================================
80     [..]  This section provides functions allowing to:
81       (+) Start conversion.
82       (+) Stop conversion.
83       (+) Start conversion and enable DMA transfer.
84       (+) Stop conversion and disable DMA transfer.
85       (+) Get result of conversion.
86       (+) Get result of dual mode conversion.
87 
88 @endverbatim
89   * @{
90   */
91 
92 
93 /**
94   * @brief  Enables DAC and starts conversion of both channels.
95   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
96   *         the configuration information for the specified DAC.
97   * @retval HAL status
98   */
HAL_DACEx_DualStart(DAC_HandleTypeDef * hdac)99 HAL_StatusTypeDef HAL_DACEx_DualStart(DAC_HandleTypeDef *hdac)
100 {
101   uint32_t tmp_swtrig = 0UL;
102 
103 
104   /* Process locked */
105   __HAL_LOCK(hdac);
106 
107   /* Change DAC state */
108   hdac->State = HAL_DAC_STATE_BUSY;
109 
110   /* Enable the Peripheral */
111   __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_1);
112   __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_2);
113 
114   /* Check if software trigger enabled */
115   if ((hdac->Instance->CR & (DAC_CR_TEN1 | DAC_CR_TSEL1)) == DAC_TRIGGER_SOFTWARE)
116   {
117     tmp_swtrig |= DAC_SWTRIGR_SWTRIG1;
118   }
119   if ((hdac->Instance->CR & (DAC_CR_TEN2 | DAC_CR_TSEL2)) == (DAC_TRIGGER_SOFTWARE << (DAC_CHANNEL_2 & 0x10UL)))
120   {
121     tmp_swtrig |= DAC_SWTRIGR_SWTRIG2;
122   }
123   /* Enable the selected DAC software conversion*/
124   SET_BIT(hdac->Instance->SWTRIGR, tmp_swtrig);
125 
126   /* Change DAC state */
127   hdac->State = HAL_DAC_STATE_READY;
128 
129   /* Process unlocked */
130   __HAL_UNLOCK(hdac);
131 
132   /* Return function status */
133   return HAL_OK;
134 }
135 
136 /**
137   * @brief  Disables DAC and stop conversion of both channels.
138   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
139   *         the configuration information for the specified DAC.
140   * @retval HAL status
141   */
HAL_DACEx_DualStop(DAC_HandleTypeDef * hdac)142 HAL_StatusTypeDef HAL_DACEx_DualStop(DAC_HandleTypeDef *hdac)
143 {
144 
145   /* Disable the Peripheral */
146   __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_1);
147   __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_2);
148 
149   /* Change DAC state */
150   hdac->State = HAL_DAC_STATE_READY;
151 
152   /* Return function status */
153   return HAL_OK;
154 }
155 
156 
157 /**
158   * @brief  Enable or disable the selected DAC channel wave generation.
159   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
160   *         the configuration information for the specified DAC.
161   * @param  Channel The selected DAC channel.
162   *          This parameter can be one of the following values:
163   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
164   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
165   * @param  Amplitude Select max triangle amplitude.
166   *          This parameter can be one of the following values:
167   *            @arg DAC_TRIANGLEAMPLITUDE_1: Select max triangle amplitude of 1
168   *            @arg DAC_TRIANGLEAMPLITUDE_3: Select max triangle amplitude of 3
169   *            @arg DAC_TRIANGLEAMPLITUDE_7: Select max triangle amplitude of 7
170   *            @arg DAC_TRIANGLEAMPLITUDE_15: Select max triangle amplitude of 15
171   *            @arg DAC_TRIANGLEAMPLITUDE_31: Select max triangle amplitude of 31
172   *            @arg DAC_TRIANGLEAMPLITUDE_63: Select max triangle amplitude of 63
173   *            @arg DAC_TRIANGLEAMPLITUDE_127: Select max triangle amplitude of 127
174   *            @arg DAC_TRIANGLEAMPLITUDE_255: Select max triangle amplitude of 255
175   *            @arg DAC_TRIANGLEAMPLITUDE_511: Select max triangle amplitude of 511
176   *            @arg DAC_TRIANGLEAMPLITUDE_1023: Select max triangle amplitude of 1023
177   *            @arg DAC_TRIANGLEAMPLITUDE_2047: Select max triangle amplitude of 2047
178   *            @arg DAC_TRIANGLEAMPLITUDE_4095: Select max triangle amplitude of 4095
179   * @retval HAL status
180   */
HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef * hdac,uint32_t Channel,uint32_t Amplitude)181 HAL_StatusTypeDef HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Amplitude)
182 {
183   /* Check the parameters */
184   assert_param(IS_DAC_CHANNEL(Channel));
185   assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude));
186 
187   /* Process locked */
188   __HAL_LOCK(hdac);
189 
190   /* Change DAC state */
191   hdac->State = HAL_DAC_STATE_BUSY;
192 
193   /* Enable the triangle wave generation for the selected DAC channel */
194   MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1) | (DAC_CR_MAMP1)) << (Channel & 0x10UL),
195              (DAC_CR_WAVE1_1 | Amplitude) << (Channel & 0x10UL));
196 
197   /* Change DAC state */
198   hdac->State = HAL_DAC_STATE_READY;
199 
200   /* Process unlocked */
201   __HAL_UNLOCK(hdac);
202 
203   /* Return function status */
204   return HAL_OK;
205 }
206 
207 /**
208   * @brief  Enable or disable the selected DAC channel wave generation.
209   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
210   *         the configuration information for the specified DAC.
211   * @param  Channel The selected DAC channel.
212   *          This parameter can be one of the following values:
213   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
214   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
215   * @param  Amplitude Unmask DAC channel LFSR for noise wave generation.
216   *          This parameter can be one of the following values:
217   *            @arg DAC_LFSRUNMASK_BIT0: Unmask DAC channel LFSR bit0 for noise wave generation
218   *            @arg DAC_LFSRUNMASK_BITS1_0: Unmask DAC channel LFSR bit[1:0] for noise wave generation
219   *            @arg DAC_LFSRUNMASK_BITS2_0: Unmask DAC channel LFSR bit[2:0] for noise wave generation
220   *            @arg DAC_LFSRUNMASK_BITS3_0: Unmask DAC channel LFSR bit[3:0] for noise wave generation
221   *            @arg DAC_LFSRUNMASK_BITS4_0: Unmask DAC channel LFSR bit[4:0] for noise wave generation
222   *            @arg DAC_LFSRUNMASK_BITS5_0: Unmask DAC channel LFSR bit[5:0] for noise wave generation
223   *            @arg DAC_LFSRUNMASK_BITS6_0: Unmask DAC channel LFSR bit[6:0] for noise wave generation
224   *            @arg DAC_LFSRUNMASK_BITS7_0: Unmask DAC channel LFSR bit[7:0] for noise wave generation
225   *            @arg DAC_LFSRUNMASK_BITS8_0: Unmask DAC channel LFSR bit[8:0] for noise wave generation
226   *            @arg DAC_LFSRUNMASK_BITS9_0: Unmask DAC channel LFSR bit[9:0] for noise wave generation
227   *            @arg DAC_LFSRUNMASK_BITS10_0: Unmask DAC channel LFSR bit[10:0] for noise wave generation
228   *            @arg DAC_LFSRUNMASK_BITS11_0: Unmask DAC channel LFSR bit[11:0] for noise wave generation
229   * @retval HAL status
230   */
HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef * hdac,uint32_t Channel,uint32_t Amplitude)231 HAL_StatusTypeDef HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Amplitude)
232 {
233   /* Check the parameters */
234   assert_param(IS_DAC_CHANNEL(Channel));
235   assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude));
236 
237   /* Process locked */
238   __HAL_LOCK(hdac);
239 
240   /* Change DAC state */
241   hdac->State = HAL_DAC_STATE_BUSY;
242 
243   /* Enable the noise wave generation for the selected DAC channel */
244   MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1) | (DAC_CR_MAMP1)) << (Channel & 0x10UL),
245              (DAC_CR_WAVE1_0 | Amplitude) << (Channel & 0x10UL));
246 
247   /* Change DAC state */
248   hdac->State = HAL_DAC_STATE_READY;
249 
250   /* Process unlocked */
251   __HAL_UNLOCK(hdac);
252 
253   /* Return function status */
254   return HAL_OK;
255 }
256 
257 
258 /**
259   * @brief  Set the specified data holding register value for dual DAC channel.
260   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
261   *               the configuration information for the specified DAC.
262   * @param  Alignment Specifies the data alignment for dual channel DAC.
263   *          This parameter can be one of the following values:
264   *            DAC_ALIGN_8B_R: 8bit right data alignment selected
265   *            DAC_ALIGN_12B_L: 12bit left data alignment selected
266   *            DAC_ALIGN_12B_R: 12bit right data alignment selected
267   * @param  Data1 Data for DAC Channel1 to be loaded in the selected data holding register.
268   * @param  Data2 Data for DAC Channel2 to be loaded in the selected data  holding register.
269   * @note   In dual mode, a unique register access is required to write in both
270   *          DAC channels at the same time.
271   * @retval HAL status
272   */
HAL_DACEx_DualSetValue(DAC_HandleTypeDef * hdac,uint32_t Alignment,uint32_t Data1,uint32_t Data2)273 HAL_StatusTypeDef HAL_DACEx_DualSetValue(DAC_HandleTypeDef *hdac, uint32_t Alignment, uint32_t Data1, uint32_t Data2)
274 {
275   uint32_t data;
276   uint32_t tmp;
277 
278   /* Check the parameters */
279   assert_param(IS_DAC_ALIGN(Alignment));
280   assert_param(IS_DAC_DATA(Data1));
281   assert_param(IS_DAC_DATA(Data2));
282 
283   /* Calculate and set dual DAC data holding register value */
284   if (Alignment == DAC_ALIGN_8B_R)
285   {
286     data = ((uint32_t)Data2 << 8U) | Data1;
287   }
288   else
289   {
290     data = ((uint32_t)Data2 << 16U) | Data1;
291   }
292 
293   tmp = (uint32_t)hdac->Instance;
294   tmp += DAC_DHR12RD_ALIGNMENT(Alignment);
295 
296   /* Set the dual DAC selected data holding register */
297   *(__IO uint32_t *)tmp = data;
298 
299   /* Return function status */
300   return HAL_OK;
301 }
302 
303 /**
304   * @brief  Conversion complete callback in non-blocking mode for Channel2.
305   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
306   *         the configuration information for the specified DAC.
307   * @retval None
308   */
HAL_DACEx_ConvCpltCallbackCh2(DAC_HandleTypeDef * hdac)309 __weak void HAL_DACEx_ConvCpltCallbackCh2(DAC_HandleTypeDef *hdac)
310 {
311   /* Prevent unused argument(s) compilation warning */
312   UNUSED(hdac);
313 
314   /* NOTE : This function should not be modified, when the callback is needed,
315             the HAL_DACEx_ConvCpltCallbackCh2 could be implemented in the user file
316    */
317 }
318 
319 /**
320   * @brief  Conversion half DMA transfer callback in non-blocking mode for Channel2.
321   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
322   *         the configuration information for the specified DAC.
323   * @retval None
324   */
HAL_DACEx_ConvHalfCpltCallbackCh2(DAC_HandleTypeDef * hdac)325 __weak void HAL_DACEx_ConvHalfCpltCallbackCh2(DAC_HandleTypeDef *hdac)
326 {
327   /* Prevent unused argument(s) compilation warning */
328   UNUSED(hdac);
329 
330   /* NOTE : This function should not be modified, when the callback is needed,
331             the HAL_DACEx_ConvHalfCpltCallbackCh2 could be implemented in the user file
332    */
333 }
334 
335 /**
336   * @brief  Error DAC callback for Channel2.
337   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
338   *         the configuration information for the specified DAC.
339   * @retval None
340   */
HAL_DACEx_ErrorCallbackCh2(DAC_HandleTypeDef * hdac)341 __weak void HAL_DACEx_ErrorCallbackCh2(DAC_HandleTypeDef *hdac)
342 {
343   /* Prevent unused argument(s) compilation warning */
344   UNUSED(hdac);
345 
346   /* NOTE : This function should not be modified, when the callback is needed,
347             the HAL_DACEx_ErrorCallbackCh2 could be implemented in the user file
348    */
349 }
350 
351 /**
352   * @brief  DMA underrun DAC callback for Channel2.
353   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
354   *         the configuration information for the specified DAC.
355   * @retval None
356   */
HAL_DACEx_DMAUnderrunCallbackCh2(DAC_HandleTypeDef * hdac)357 __weak void HAL_DACEx_DMAUnderrunCallbackCh2(DAC_HandleTypeDef *hdac)
358 {
359   /* Prevent unused argument(s) compilation warning */
360   UNUSED(hdac);
361 
362   /* NOTE : This function should not be modified, when the callback is needed,
363             the HAL_DACEx_DMAUnderrunCallbackCh2 could be implemented in the user file
364    */
365 }
366 
367 
368 
369 /**
370   * @}
371   */
372 
373 /** @defgroup DACEx_Exported_Functions_Group3 Peripheral Control functions
374   *  @brief    Extended Peripheral Control functions
375   *
376 @verbatim
377   ==============================================================================
378              ##### Peripheral Control functions #####
379   ==============================================================================
380     [..]  This section provides functions allowing to:
381       (+) Set the specified data holding register value for DAC channel.
382 
383 @endverbatim
384   * @{
385   */
386 
387 
388 /**
389   * @brief  Return the last data output value of the selected DAC channel.
390   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
391   *         the configuration information for the specified DAC.
392   * @retval The selected DAC channel data output value.
393   */
HAL_DACEx_DualGetValue(DAC_HandleTypeDef * hdac)394 uint32_t HAL_DACEx_DualGetValue(DAC_HandleTypeDef *hdac)
395 {
396   uint32_t tmp = 0UL;
397 
398   tmp |= hdac->Instance->DOR1;
399 
400   tmp |= hdac->Instance->DOR2 << 16UL;
401 
402   /* Returns the DAC channel data output register value */
403   return tmp;
404 }
405 
406 
407 /**
408   * @}
409   */
410 /**
411   * @}
412   */
413 
414 /* Private functions ---------------------------------------------------------*/
415 /** @defgroup DACEx_Private_Functions DACEx private functions
416   *  @brief    Extended private functions
417   * @{
418   */
419 
420 
421 /**
422   * @brief  DMA conversion complete callback.
423   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
424   *                the configuration information for the specified DMA module.
425   * @retval None
426   */
DAC_DMAConvCpltCh2(DMA_HandleTypeDef * hdma)427 void DAC_DMAConvCpltCh2(DMA_HandleTypeDef *hdma)
428 {
429   DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
430 
431 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
432   hdac->ConvCpltCallbackCh2(hdac);
433 #else
434   HAL_DACEx_ConvCpltCallbackCh2(hdac);
435 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
436 
437   hdac->State = HAL_DAC_STATE_READY;
438 }
439 
440 /**
441   * @brief  DMA half transfer complete callback.
442   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
443   *                the configuration information for the specified DMA module.
444   * @retval None
445   */
DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef * hdma)446 void DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef *hdma)
447 {
448   DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
449   /* Conversion complete callback */
450 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
451   hdac->ConvHalfCpltCallbackCh2(hdac);
452 #else
453   HAL_DACEx_ConvHalfCpltCallbackCh2(hdac);
454 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
455 }
456 
457 /**
458   * @brief  DMA error callback.
459   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
460   *                the configuration information for the specified DMA module.
461   * @retval None
462   */
DAC_DMAErrorCh2(DMA_HandleTypeDef * hdma)463 void DAC_DMAErrorCh2(DMA_HandleTypeDef *hdma)
464 {
465   DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
466 
467   /* Set DAC error code to DMA error */
468   hdac->ErrorCode |= HAL_DAC_ERROR_DMA;
469 
470 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
471   hdac->ErrorCallbackCh2(hdac);
472 #else
473   HAL_DACEx_ErrorCallbackCh2(hdac);
474 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
475 
476   hdac->State = HAL_DAC_STATE_READY;
477 }
478 
479 
480 /**
481   * @}
482   */
483 
484 /**
485   * @}
486   */
487 
488 #endif /* DAC */
489 
490 #endif /* HAL_DAC_MODULE_ENABLED */
491 
492 /**
493   * @}
494   */
495 
496