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