1 /**
2   ******************************************************************************
3   * @file    stm32h5xx_hal_dac.c
4   * @author  MCD Application Team
5   * @brief   DAC HAL module driver.
6   *         This file provides firmware functions to manage the following
7   *         functionalities of the Digital to Analog Converter (DAC) peripheral:
8   *           + Initialization and de-initialization functions
9   *           + IO operation functions
10   *           + Peripheral Control functions
11   *           + Peripheral State and Errors functions
12   *
13   *
14   ******************************************************************************
15   * @attention
16   *
17   * Copyright (c) 2022 STMicroelectronics.
18   * All rights reserved.
19   *
20   * This software is licensed under terms that can be found in the LICENSE file
21   * in the root directory of this software component.
22   * If no LICENSE file comes with this software, it is provided AS-IS.
23   *
24   ******************************************************************************
25   @verbatim
26   ==============================================================================
27                       ##### DAC Peripheral features #####
28   ==============================================================================
29     [..]
30       *** DAC Channels ***
31       ====================
32     [..]
33     STM32H5 devices integrate two 12-bit Digital Analog Converters
34 
35     The 2 converters (i.e. channel1 & channel2)
36     can be used independently or simultaneously (dual mode):
37       (#) DAC channel1 with DAC_OUT1 (PA4) as output or connected to on-chip
38           peripherals (ex. ADC).
39       (#) DAC channel2 with DAC_OUT2 (PA5) as output or connected to on-chip
40           peripherals (ex. ADC).
41 
42       *** DAC Triggers ***
43       ====================
44     [..]
45     Digital to Analog conversion can be non-triggered using DAC_TRIGGER_NONE
46     and DAC_OUT1/DAC_OUT2 is available once writing to DHRx register.
47     [..]
48     Digital to Analog conversion can be triggered by:
49       (#) External event: EXTI Line 9 (any GPIOx_PIN_9) using DAC_TRIGGER_EXT_IT9.
50           The used pin (GPIOx_PIN_9) must be configured in input mode.
51 
52       (#) Timers TRGO: TIM1, TIM2, TIM3, TIM4, TIM5, TIM6, TIM7, TIM8 and TIM15
53           (DAC_TRIGGER_T1_TRGO, DAC_TRIGGER_T2_TRGO...)
54 
55       (#) Low Power Timers CH1: LPTIM1 and LPTIM2
56           (DAC_TRIGGER_LPTIM1_CH1, DAC_TRIGGER_LPTIM2_CH1)
57 
58       (#) Software using DAC_TRIGGER_SOFTWARE
59     [..]
60   The trigger selection depends on the PWR mode:
61   in stop0, stop1 and stop2 we should select DAC_TRIGGER_EXT_IT9,
62     DAC_TRIGGER_LPTIM1_CH1 or DAC_TRIGGER_LPTIM2_CH1.The other triggers
63   are not functional.
64       *** DAC Buffer mode feature ***
65       ===============================
66       [..]
67       Each DAC channel integrates an output buffer that can be used to
68       reduce the output impedance, and to drive external loads directly
69       without having to add an external operational amplifier.
70       To enable, the output buffer use
71       sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
72       [..]
73       (@) Refer to the device datasheet for more details about output
74           impedance value with and without output buffer.
75 
76       *** GPIO configurations guidelines ***
77       =====================
78       [..]
79       When a DAC channel is used (ex channel1 on PA4) and the other is not
80       (ex channel2 on PA5 is configured in Analog and disabled).
81       Channel1 may disturb channel2 as coupling effect.
82       Note that there is no coupling on channel2 as soon as channel2 is turned on.
83       Coupling on adjacent channel could be avoided as follows:
84       when unused PA5 is configured as INPUT PULL-UP or DOWN.
85       PA5 is configured in ANALOG just before it is turned on.
86 
87       *** DAC Sample and Hold feature ***
88       ========================
89       [..]
90       For each converter, 2 modes are supported: normal mode and
91       "sample and hold" mode (i.e. low power mode).
92       In the sample and hold mode, the DAC core converts data, then holds the
93       converted voltage on a capacitor. When not converting, the DAC cores and
94       buffer are completely turned off between samples and the DAC output is
95       tri-stated, therefore  reducing the overall power consumption. A new
96       stabilization period is needed before each new conversion.
97 
98       The sample and hold allow setting internal or external voltage @
99       low power consumption cost (output value can be at any given rate either
100       by CPU or DMA).
101 
102       The Sample and hold block and registers uses either LSI & run in
103       several power modes: run mode, sleep mode, low power run, low power sleep
104       mode & stop1 mode.
105 
106       Low power stop1 mode allows only static conversion.
107 
108       To enable Sample and Hold mode
109       Enable LSI using HAL_RCC_OscConfig with RCC_OSCILLATORTYPE_LSI &
110       RCC_LSI_ON parameters.
111 
112       Use DAC_InitStructure.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_ENABLE;
113          & DAC_ChannelConfTypeDef.DAC_SampleAndHoldConfig.DAC_SampleTime,
114            DAC_HoldTime & DAC_RefreshTime;
115 
116        *** DAC calibration feature ***
117        ===================================
118       [..]
119        (#)  The 2 converters (channel1 & channel2) provide calibration capabilities.
120        (++) Calibration aims at correcting some offset of output buffer.
121        (++) The DAC uses either factory calibration settings OR user defined
122            calibration (trimming) settings (i.e. trimming mode).
123        (++) The user defined settings can be figured out using self calibration
124            handled by HAL_DACEx_SelfCalibrate.
125        (++) HAL_DACEx_SelfCalibrate:
126        (+++) Runs automatically the calibration.
127        (+++) Enables the user trimming mode
128        (+++) Updates a structure with trimming values with fresh calibration
129             results.
130             The user may store the calibration results for larger
131             (ex monitoring the trimming as a function of temperature
132             for instance)
133 
134        *** DAC wave generation feature ***
135        ===================================
136        [..]
137        Both DAC channels can be used to generate
138          (#) Noise wave
139          (#) Triangle wave
140 
141        *** DAC data format ***
142        =======================
143        [..]
144        The DAC data format can be:
145          (#) 8-bit right alignment using DAC_ALIGN_8B_R
146          (#) 12-bit left alignment using DAC_ALIGN_12B_L
147          (#) 12-bit right alignment using DAC_ALIGN_12B_R
148 
149        *** DAC data value to voltage correspondence ***
150        ================================================
151        [..]
152        The analog output voltage on each DAC channel pin is determined
153        by the following equation:
154        [..]
155        DAC_OUTx = VREF+ * DOR / 4095
156        (+) with  DOR is the Data Output Register
157        [..]
158           VREF+ is the input voltage reference (refer to the device datasheet)
159        [..]
160         e.g. To set DAC_OUT1 to 0.7V, use
161        (+) Assuming that VREF+ = 3.3V, DAC_OUT1 = (3.3 * 868) / 4095 = 0.7V
162 
163        *** DMA requests ***
164        =====================
165        [..]
166        A DMA request can be generated when an external trigger (but not a software trigger)
167        occurs if DMA requests are enabled using HAL_DAC_Start_DMA().
168        DMA requests are mapped as following:
169            GPDMA requests are mapped as following:
170              (+) DAC channel1 mapped on GPDMA request 2 (can be any GPDMA channel)
171              (+) DAC channel2 mapped on GPDMA request 3 (can be any GPDMA channel)
172 
173 
174        *** High frequency interface mode ***
175        =====================================
176        [..]
177        The high frequency interface informs DAC instance about the bus frequency in use.
178        It is mandatory information for DAC (as internal timing of DAC is bus frequency dependent)
179        provided thanks to parameter DAC_HighFrequency handled in HAL_DAC_ConfigChannel () function.
180        Use of DAC_HIGH_FREQUENCY_INTERFACE_MODE_AUTOMATIC value of DAC_HighFrequency is recommended
181        function figured out the correct setting.
182        The high frequency mode is same for all converters of a same DAC instance. Either same
183        parameter DAC_HighFrequency is used for all DAC converters or again self
184        DAC_HIGH_FREQUENCY_INTERFACE_MODE_AUTOMATIC detection parameter.
185 
186      [..]
187     (@) For Dual mode and specific signal (Triangle and noise) generation please
188         refer to Extended Features Driver description
189 
190                       ##### How to use this driver #####
191   ==============================================================================
192     [..]
193       (+) DAC APB clock must be enabled to get write access to DAC
194           registers using HAL_DAC_Init()
195       (+) Configure DAC_OUTx (DAC_OUT1: PA4, DAC_OUT2: PA5) in analog mode.
196       (+) Configure the DAC channel using HAL_DAC_ConfigChannel() function.
197       (+) Enable the DAC channel using HAL_DAC_Start() or HAL_DAC_Start_DMA() functions.
198 
199      *** Calibration mode IO operation ***
200      ======================================
201      [..]
202        (+) Retrieve the factory trimming (calibration settings) using HAL_DACEx_GetTrimOffset()
203        (+) Run the calibration using HAL_DACEx_SelfCalibrate()
204        (+) Update the trimming while DAC running using HAL_DACEx_SetUserTrimming()
205 
206      *** Polling mode IO operation ***
207      =================================
208      [..]
209        (+) Start the DAC peripheral using HAL_DAC_Start()
210        (+) To read the DAC last data output value, use the HAL_DAC_GetValue() function.
211        (+) Stop the DAC peripheral using HAL_DAC_Stop()
212 
213      *** DMA mode IO operation ***
214      ==============================
215      [..]
216        (+) Start the DAC peripheral using HAL_DAC_Start_DMA(), at this stage the user specify the length
217            of data to be transferred at each end of conversion
218            First issued trigger will start the conversion of the value previously set by HAL_DAC_SetValue().
219        (+) At the middle of data transfer HAL_DAC_ConvHalfCpltCallbackCh1() or HAL_DACEx_ConvHalfCpltCallbackCh2()
220            function is executed and user can add his own code by customization of function pointer
221            HAL_DAC_ConvHalfCpltCallbackCh1() or HAL_DACEx_ConvHalfCpltCallbackCh2()
222        (+) At The end of data transfer HAL_DAC_ConvCpltCallbackCh1() or HAL_DACEx_ConvHalfCpltCallbackCh2()
223            function is executed and user can add his own code by customization of function pointer
224            HAL_DAC_ConvCpltCallbackCh1() or HAL_DACEx_ConvHalfCpltCallbackCh2()
225        (+) In case of transfer Error, HAL_DAC_ErrorCallbackCh1() function is executed and user can
226             add his own code by customization of function pointer HAL_DAC_ErrorCallbackCh1
227        (+) In case of DMA underrun, DAC interruption triggers and execute internal function HAL_DAC_IRQHandler.
228            HAL_DAC_DMAUnderrunCallbackCh1() or HAL_DACEx_DMAUnderrunCallbackCh2()
229            function is executed and user can add his own code by customization of function pointer
230            HAL_DAC_DMAUnderrunCallbackCh1() or HAL_DACEx_DMAUnderrunCallbackCh2() and
231            add his own code by customization of function pointer HAL_DAC_ErrorCallbackCh1()
232        (+) Stop the DAC peripheral using HAL_DAC_Stop_DMA()
233 
234     *** Callback registration ***
235     =============================================
236     [..]
237       The compilation define  USE_HAL_DAC_REGISTER_CALLBACKS when set to 1
238       allows the user to configure dynamically the driver callbacks.
239 
240     Use Functions @ref HAL_DAC_RegisterCallback() to register a user callback,
241       it allows to register following callbacks:
242       (+) ConvCpltCallbackCh1     : callback when a half transfer is completed on Ch1.
243       (+) ConvHalfCpltCallbackCh1 : callback when a transfer is completed on Ch1.
244       (+) ErrorCallbackCh1        : callback when an error occurs on Ch1.
245       (+) DMAUnderrunCallbackCh1  : callback when an underrun error occurs on Ch1.
246       (+) ConvCpltCallbackCh2     : callback when a half transfer is completed on Ch2.
247       (+) ConvHalfCpltCallbackCh2 : callback when a transfer is completed on Ch2.
248       (+) ErrorCallbackCh2        : callback when an error occurs on Ch2.
249       (+) DMAUnderrunCallbackCh2  : callback when an underrun error occurs on Ch2.
250       (+) MspInitCallback         : DAC MspInit.
251       (+) MspDeInitCallback       : DAC MspdeInit.
252       This function takes as parameters the HAL peripheral handle, the Callback ID
253       and a pointer to the user callback function.
254 
255     Use function @ref HAL_DAC_UnRegisterCallback() to reset a callback to the default
256       weak (surcharged) function. It allows to reset following callbacks:
257       (+) ConvCpltCallbackCh1     : callback when a half transfer is completed on Ch1.
258       (+) ConvHalfCpltCallbackCh1 : callback when a transfer is completed on Ch1.
259       (+) ErrorCallbackCh1        : callback when an error occurs on Ch1.
260       (+) DMAUnderrunCallbackCh1  : callback when an underrun error occurs on Ch1.
261       (+) ConvCpltCallbackCh2     : callback when a half transfer is completed on Ch2.
262       (+) ConvHalfCpltCallbackCh2 : callback when a transfer is completed on Ch2.
263       (+) ErrorCallbackCh2        : callback when an error occurs on Ch2.
264       (+) DMAUnderrunCallbackCh2  : callback when an underrun error occurs on Ch2.
265       (+) MspInitCallback         : DAC MspInit.
266       (+) MspDeInitCallback       : DAC MspdeInit.
267       (+) All Callbacks
268       This function) takes as parameters the HAL peripheral handle and the Callback ID.
269 
270       By default, after the @ref HAL_DAC_Init and if the state is HAL_DAC_STATE_RESET
271       all callbacks are reset to the corresponding legacy weak (surcharged) functions.
272       Exception done for MspInit and MspDeInit callbacks that are respectively
273       reset to the legacy weak (surcharged) functions in the @ref HAL_DAC_Init
274       and @ref  HAL_DAC_DeInit only when these callbacks are null (not registered beforehand).
275       If not, MspInit or MspDeInit are not null, the @ref HAL_DAC_Init and @ref HAL_DAC_DeInit
276       keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
277 
278       Callbacks can be registered/unregistered in READY state only.
279       Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
280       in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
281       during the Init/DeInit.
282       In that case first register the MspInit/MspDeInit user callbacks
283       using @ref HAL_DAC_RegisterCallback before calling @ref HAL_DAC_DeInit
284       or @ref HAL_DAC_Init function.
285 
286       When The compilation define USE_HAL_DAC_REGISTER_CALLBACKS is set to 0 or
287       not defined, the callback registering feature is not available
288       and weak (surcharged) callbacks are used.
289 
290      *** DAC HAL driver macros list ***
291      =============================================
292      [..]
293        Below the list of most used macros in DAC HAL driver.
294 
295       (+) __HAL_DAC_ENABLE : Enable the DAC peripheral
296       (+) __HAL_DAC_DISABLE : Disable the DAC peripheral
297       (+) __HAL_DAC_CLEAR_FLAG: Clear the DAC's pending flags
298       (+) __HAL_DAC_GET_FLAG: Get the selected DAC's flag status
299 
300      [..]
301       (@) You can refer to the DAC HAL driver header file for more useful macros
302 
303 @endverbatim
304   ******************************************************************************
305   */
306 
307 /* Includes ------------------------------------------------------------------*/
308 #include "stm32h5xx_hal.h"
309 
310 /** @addtogroup STM32H5xx_HAL_Driver
311   * @{
312   */
313 
314 #ifdef HAL_DAC_MODULE_ENABLED
315 #if defined(DAC1)
316 
317 /** @defgroup DAC DAC
318   * @brief DAC driver modules
319   * @{
320   */
321 
322 /* Private typedef -----------------------------------------------------------*/
323 /* Private define ------------------------------------------------------------*/
324 /* Private constants ---------------------------------------------------------*/
325 /** @addtogroup DAC_Private_Constants DAC Private Constants
326   * @{
327   */
328 #define TIMEOUT_DAC_CALIBCONFIG        1U         /* 1   ms        */
329 #define HFSEL_ENABLE_THRESHOLD_80MHZ   80000000U  /* 80 MHz        */
330 #define HFSEL_ENABLE_THRESHOLD_160MHZ  160000000U /* 160 MHz       */
331 
332 /**
333   * @}
334   */
335 
336 /* Private macro -------------------------------------------------------------*/
337 /* Private variables ---------------------------------------------------------*/
338 /* Private function prototypes -----------------------------------------------*/
339 /* Exported functions -------------------------------------------------------*/
340 
341 /** @defgroup DAC_Exported_Functions DAC Exported Functions
342   * @{
343   */
344 
345 /** @defgroup DAC_Exported_Functions_Group1 Initialization and de-initialization functions
346   *  @brief    Initialization and Configuration functions
347   *
348 @verbatim
349   ==============================================================================
350               ##### Initialization and de-initialization functions #####
351   ==============================================================================
352     [..]  This section provides functions allowing to:
353       (+) Initialize and configure the DAC.
354       (+) De-initialize the DAC.
355 
356 @endverbatim
357   * @{
358   */
359 
360 /**
361   * @brief  Initialize the DAC peripheral according to the specified parameters
362   *         in the DAC_InitStruct and initialize the associated handle.
363   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
364   *         the configuration information for the specified DAC.
365   * @retval HAL status
366   */
HAL_DAC_Init(DAC_HandleTypeDef * hdac)367 HAL_StatusTypeDef HAL_DAC_Init(DAC_HandleTypeDef *hdac)
368 {
369   /* Check the DAC peripheral handle */
370   if (hdac == NULL)
371   {
372     return HAL_ERROR;
373   }
374   /* Check the parameters */
375   assert_param(IS_DAC_ALL_INSTANCE(hdac->Instance));
376 
377   if (hdac->State == HAL_DAC_STATE_RESET)
378   {
379 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
380     /* Init the DAC Callback settings */
381     hdac->ConvCpltCallbackCh1           = HAL_DAC_ConvCpltCallbackCh1;
382     hdac->ConvHalfCpltCallbackCh1       = HAL_DAC_ConvHalfCpltCallbackCh1;
383     hdac->ErrorCallbackCh1              = HAL_DAC_ErrorCallbackCh1;
384     hdac->DMAUnderrunCallbackCh1        = HAL_DAC_DMAUnderrunCallbackCh1;
385 
386     hdac->ConvCpltCallbackCh2           = HAL_DACEx_ConvCpltCallbackCh2;
387     hdac->ConvHalfCpltCallbackCh2       = HAL_DACEx_ConvHalfCpltCallbackCh2;
388     hdac->ErrorCallbackCh2              = HAL_DACEx_ErrorCallbackCh2;
389     hdac->DMAUnderrunCallbackCh2        = HAL_DACEx_DMAUnderrunCallbackCh2;
390 
391     if (hdac->MspInitCallback == NULL)
392     {
393       hdac->MspInitCallback             = HAL_DAC_MspInit;
394     }
395 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
396 
397     /* Allocate lock resource and initialize it */
398     hdac->Lock = HAL_UNLOCKED;
399 
400 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
401     /* Init the low level hardware */
402     hdac->MspInitCallback(hdac);
403 #else
404     /* Init the low level hardware */
405     HAL_DAC_MspInit(hdac);
406 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
407   }
408 
409   /* Initialize the DAC state*/
410   hdac->State = HAL_DAC_STATE_BUSY;
411 
412   /* Set DAC error code to none */
413   hdac->ErrorCode = HAL_DAC_ERROR_NONE;
414 
415   /* Initialize the DAC state*/
416   hdac->State = HAL_DAC_STATE_READY;
417 
418   /* Return function status */
419   return HAL_OK;
420 }
421 
422 /**
423   * @brief  Deinitialize the DAC peripheral registers to their default reset values.
424   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
425   *         the configuration information for the specified DAC.
426   * @retval HAL status
427   */
HAL_DAC_DeInit(DAC_HandleTypeDef * hdac)428 HAL_StatusTypeDef HAL_DAC_DeInit(DAC_HandleTypeDef *hdac)
429 {
430   /* Check the DAC peripheral handle */
431   if (hdac == NULL)
432   {
433     return HAL_ERROR;
434   }
435 
436   /* Check the parameters */
437   assert_param(IS_DAC_ALL_INSTANCE(hdac->Instance));
438 
439   /* Change DAC state */
440   hdac->State = HAL_DAC_STATE_BUSY;
441 
442 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
443   if (hdac->MspDeInitCallback == NULL)
444   {
445     hdac->MspDeInitCallback = HAL_DAC_MspDeInit;
446   }
447   /* DeInit the low level hardware */
448   hdac->MspDeInitCallback(hdac);
449 #else
450   /* DeInit the low level hardware */
451   HAL_DAC_MspDeInit(hdac);
452 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
453 
454   /* Set DAC error code to none */
455   hdac->ErrorCode = HAL_DAC_ERROR_NONE;
456 
457   /* Change DAC state */
458   hdac->State = HAL_DAC_STATE_RESET;
459 
460   /* Release Lock */
461   __HAL_UNLOCK(hdac);
462 
463   /* Return function status */
464   return HAL_OK;
465 }
466 
467 /**
468   * @brief  Initialize the DAC MSP.
469   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
470   *         the configuration information for the specified DAC.
471   * @retval None
472   */
HAL_DAC_MspInit(DAC_HandleTypeDef * hdac)473 __weak void HAL_DAC_MspInit(DAC_HandleTypeDef *hdac)
474 {
475   /* Prevent unused argument(s) compilation warning */
476   UNUSED(hdac);
477 
478   /* NOTE : This function should not be modified, when the callback is needed,
479             the HAL_DAC_MspInit could be implemented in the user file
480    */
481 }
482 
483 /**
484   * @brief  DeInitialize the DAC MSP.
485   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
486   *         the configuration information for the specified DAC.
487   * @retval None
488   */
HAL_DAC_MspDeInit(DAC_HandleTypeDef * hdac)489 __weak void HAL_DAC_MspDeInit(DAC_HandleTypeDef *hdac)
490 {
491   /* Prevent unused argument(s) compilation warning */
492   UNUSED(hdac);
493 
494   /* NOTE : This function should not be modified, when the callback is needed,
495             the HAL_DAC_MspDeInit could be implemented in the user file
496    */
497 }
498 
499 /**
500   * @}
501   */
502 
503 /** @defgroup DAC_Exported_Functions_Group2 IO operation functions
504   *  @brief    IO operation functions
505   *
506 @verbatim
507   ==============================================================================
508              ##### IO operation functions #####
509   ==============================================================================
510     [..]  This section provides functions allowing to:
511       (+) Start conversion.
512       (+) Stop conversion.
513       (+) Start conversion and enable DMA transfer.
514       (+) Stop conversion and disable DMA transfer.
515       (+) Get result of conversion.
516 
517 @endverbatim
518   * @{
519   */
520 
521 /**
522   * @brief  Enables DAC and starts conversion of channel.
523   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
524   *         the configuration information for the specified DAC.
525   * @param  Channel The selected DAC channel.
526   *          This parameter can be one of the following values:
527   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
528   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
529   * @retval HAL status
530   */
HAL_DAC_Start(DAC_HandleTypeDef * hdac,uint32_t Channel)531 HAL_StatusTypeDef HAL_DAC_Start(DAC_HandleTypeDef *hdac, uint32_t Channel)
532 {
533   __IO uint32_t wait_loop_index;
534 
535   /* Check the DAC peripheral handle */
536   if (hdac == NULL)
537   {
538     return HAL_ERROR;
539   }
540 
541   /* Check the parameters */
542   assert_param(IS_DAC_CHANNEL(Channel));
543 
544   /* Process locked */
545   __HAL_LOCK(hdac);
546 
547   /* Change DAC state */
548   hdac->State = HAL_DAC_STATE_BUSY;
549 
550   /* Enable the Peripheral */
551   __HAL_DAC_ENABLE(hdac, Channel);
552   /* Ensure minimum wait before using peripheral after enabling it */
553   /* Wait loop initialization and execution */
554   /* Note: Variable divided by 2 to compensate partially CPU processing cycles, scaling in us split to not exceed 32 */
555   /*       bits register capacity and handle low frequency. */
556   wait_loop_index = ((DAC_DELAY_STARTUP_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
557   while(wait_loop_index != 0UL)
558   {
559     wait_loop_index--;
560   }
561 
562   if (Channel == DAC_CHANNEL_1)
563   {
564     /* Check if software trigger enabled */
565     if ((hdac->Instance->CR & (DAC_CR_TEN1 | DAC_CR_TSEL1)) == DAC_TRIGGER_SOFTWARE)
566     {
567       /* Enable the selected DAC software conversion */
568       SET_BIT(hdac->Instance->SWTRIGR, DAC_SWTRIGR_SWTRIG1);
569     }
570   }
571 
572   else
573   {
574     /* Check if software trigger enabled */
575     if ((hdac->Instance->CR & (DAC_CR_TEN2 | DAC_CR_TSEL2)) == (DAC_TRIGGER_SOFTWARE << (Channel & 0x10UL)))
576     {
577       /* Enable the selected DAC software conversion*/
578       SET_BIT(hdac->Instance->SWTRIGR, DAC_SWTRIGR_SWTRIG2);
579     }
580   }
581 
582 
583   /* Change DAC state */
584   hdac->State = HAL_DAC_STATE_READY;
585 
586   /* Process unlocked */
587   __HAL_UNLOCK(hdac);
588 
589   /* Return function status */
590   return HAL_OK;
591 }
592 
593 /**
594   * @brief  Disables DAC and stop conversion of channel.
595   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
596   *         the configuration information for the specified DAC.
597   * @param  Channel The selected DAC channel.
598   *          This parameter can be one of the following values:
599   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
600   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
601   * @retval HAL status
602   */
HAL_DAC_Stop(DAC_HandleTypeDef * hdac,uint32_t Channel)603 HAL_StatusTypeDef HAL_DAC_Stop(DAC_HandleTypeDef *hdac, uint32_t Channel)
604 {
605   /* Check the DAC peripheral handle */
606   if (hdac == NULL)
607   {
608     return HAL_ERROR;
609   }
610 
611   /* Check the parameters */
612   assert_param(IS_DAC_CHANNEL(Channel));
613 
614   /* Disable the Peripheral */
615   __HAL_DAC_DISABLE(hdac, Channel);
616 
617   /* Change DAC state */
618   hdac->State = HAL_DAC_STATE_READY;
619 
620   /* Return function status */
621   return HAL_OK;
622 }
623 
624 /**
625   * @brief  Enables DAC and starts conversion of channel.
626   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
627   *         the configuration information for the specified DAC.
628   * @param  Channel The selected DAC channel.
629   *          This parameter can be one of the following values:
630   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
631   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
632   * @param  pData The source Buffer address.
633   * @param  Length The length of data to be transferred from memory to DAC peripheral
634   * @param  Alignment Specifies the data alignment for DAC channel.
635   *          This parameter can be one of the following values:
636   *            @arg DAC_ALIGN_8B_R: 8bit right data alignment selected
637   *            @arg DAC_ALIGN_12B_L: 12bit left data alignment selected
638   *            @arg DAC_ALIGN_12B_R: 12bit right data alignment selected
639   * @retval HAL status
640   */
HAL_DAC_Start_DMA(DAC_HandleTypeDef * hdac,uint32_t Channel,const uint32_t * pData,uint32_t Length,uint32_t Alignment)641 HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel, const uint32_t *pData, uint32_t Length,
642                                     uint32_t Alignment)
643 {
644   HAL_StatusTypeDef status;
645   uint32_t tmpreg = 0U;
646   uint32_t LengthInBytes;
647   DMA_NodeConfTypeDef node_conf;
648   __IO uint32_t wait_loop_index;
649 
650   /* Check the DAC peripheral handle */
651   if (hdac == NULL)
652   {
653     return HAL_ERROR;
654   }
655 
656   /* Check the parameters */
657   assert_param(IS_DAC_CHANNEL(Channel));
658   assert_param(IS_DAC_ALIGN(Alignment));
659 
660   /* Process locked */
661   __HAL_LOCK(hdac);
662 
663   /* Change DAC state */
664   hdac->State = HAL_DAC_STATE_BUSY;
665 
666   if (Channel == DAC_CHANNEL_1)
667   {
668     /* Set the DMA transfer complete callback for channel1 */
669     hdac->DMA_Handle1->XferCpltCallback = DAC_DMAConvCpltCh1;
670 
671     /* Set the DMA half transfer complete callback for channel1 */
672     hdac->DMA_Handle1->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh1;
673 
674     /* Set the DMA error callback for channel1 */
675     hdac->DMA_Handle1->XferErrorCallback = DAC_DMAErrorCh1;
676 
677     /* Enable the selected DAC channel1 DMA request */
678     SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN1);
679 
680     /* Case of use of channel 1 */
681     switch (Alignment)
682     {
683       case DAC_ALIGN_12B_R:
684         /* Get DHR12R1 address */
685         tmpreg = (uint32_t)&hdac->Instance->DHR12R1;
686         break;
687       case DAC_ALIGN_12B_L:
688         /* Get DHR12L1 address */
689         tmpreg = (uint32_t)&hdac->Instance->DHR12L1;
690         break;
691       default: /* case DAC_ALIGN_8B_R */
692         /* Get DHR8R1 address */
693         tmpreg = (uint32_t)&hdac->Instance->DHR8R1;
694         break;
695     }
696   }
697 
698   else
699   {
700     /* Set the DMA transfer complete callback for channel2 */
701     hdac->DMA_Handle2->XferCpltCallback = DAC_DMAConvCpltCh2;
702 
703     /* Set the DMA half transfer complete callback for channel2 */
704     hdac->DMA_Handle2->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh2;
705 
706     /* Set the DMA error callback for channel2 */
707     hdac->DMA_Handle2->XferErrorCallback = DAC_DMAErrorCh2;
708 
709     /* Enable the selected DAC channel2 DMA request */
710     SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN2);
711 
712     /* Case of use of channel 2 */
713     switch (Alignment)
714     {
715       case DAC_ALIGN_12B_R:
716         /* Get DHR12R2 address */
717         tmpreg = (uint32_t)&hdac->Instance->DHR12R2;
718         break;
719       case DAC_ALIGN_12B_L:
720         /* Get DHR12L2 address */
721         tmpreg = (uint32_t)&hdac->Instance->DHR12L2;
722         break;
723       default: /* case DAC_ALIGN_8B_R */
724         /* Get DHR8R2 address */
725         tmpreg = (uint32_t)&hdac->Instance->DHR8R2;
726         break;
727     }
728   }
729 
730 
731   /* Enable the DMA channel */
732   if (Channel == DAC_CHANNEL_1)
733   {
734     /* Enable the DAC DMA underrun interrupt */
735     __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR1);
736 
737     /* Enable the DMA channel */
738     /* Check linkedlist mode */
739     if ((hdac->DMA_Handle1->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
740     {
741       if ((hdac->DMA_Handle1->LinkedListQueue != NULL) && (hdac->DMA_Handle1->LinkedListQueue->Head != NULL))
742       {
743         /* Length should be converted to number of bytes */
744         if (HAL_DMAEx_List_GetNodeConfig(&node_conf, hdac->DMA_Handle1->LinkedListQueue->Head) != HAL_OK)
745         {
746           return HAL_ERROR;
747         }
748 
749         /* Length should be converted to number of bytes */
750         if (node_conf.Init.SrcDataWidth == DMA_SRC_DATAWIDTH_WORD)
751         {
752           /* Word -> Bytes */
753           LengthInBytes = Length * 4U;
754         }
755         else if (node_conf.Init.SrcDataWidth == DMA_SRC_DATAWIDTH_HALFWORD)
756         {
757           /* Halfword -> Bytes */
758           LengthInBytes = Length * 2U;
759         }
760         else /* Bytes */
761         {
762           /* Same size already expressed in Bytes */
763           LengthInBytes = Length;
764         }
765 
766         /* Set DMA data size */
767         hdac->DMA_Handle1->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = LengthInBytes;
768 
769         /* Set DMA source address */
770         hdac->DMA_Handle1->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pData;
771 
772         /* Set DMA destination address */
773         hdac->DMA_Handle1->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = tmpreg;
774 
775         /* Enable the DMA channel */
776         status = HAL_DMAEx_List_Start_IT(hdac->DMA_Handle1);
777       }
778       else
779       {
780         /* Return error status */
781         return HAL_ERROR;
782       }
783     }
784     else
785     {
786       /* Length should be converted to number of bytes */
787       if (hdac->DMA_Handle1->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_WORD)
788       {
789         /* Word -> Bytes */
790         LengthInBytes = Length * 4U;
791       }
792       else if (hdac->DMA_Handle1->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_HALFWORD)
793       {
794         /* Halfword -> Bytes */
795         LengthInBytes = Length * 2U;
796       }
797       else /* Bytes */
798       {
799         /* Same size already expressed in Bytes */
800         LengthInBytes = Length;
801       }
802 
803       /* Enable the DMA channel */
804       status = HAL_DMA_Start_IT(hdac->DMA_Handle1, (uint32_t)pData, tmpreg, LengthInBytes);
805     }
806   }
807 
808   else
809   {
810     /* Enable the DAC DMA underrun interrupt */
811     __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR2);
812 
813     /* Enable the DMA channel */
814     /* Check linkedlist mode */
815     if ((hdac->DMA_Handle2->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
816     {
817       if ((hdac->DMA_Handle2->LinkedListQueue != NULL) && (hdac->DMA_Handle2->LinkedListQueue->Head != NULL))
818       {
819         /* Length should be converted to number of bytes */
820         if (HAL_DMAEx_List_GetNodeConfig(&node_conf, hdac->DMA_Handle2->LinkedListQueue->Head) != HAL_OK)
821         {
822           return HAL_ERROR;
823         }
824 
825         /* Length should be converted to number of bytes */
826         if (node_conf.Init.SrcDataWidth == DMA_SRC_DATAWIDTH_WORD)
827         {
828           /* Word -> Bytes */
829           LengthInBytes = Length * 4U;
830         }
831         else if (node_conf.Init.SrcDataWidth == DMA_SRC_DATAWIDTH_HALFWORD)
832         {
833           /* Halfword -> Bytes */
834           LengthInBytes = Length * 2U;
835         }
836         else /* Bytes */
837         {
838           /* Same size already expressed in Bytes */
839           LengthInBytes = Length;
840         }
841 
842         /* Set DMA data size */
843         hdac->DMA_Handle2->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = LengthInBytes;
844 
845         /* Set DMA source address */
846         hdac->DMA_Handle2->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pData;
847 
848         /* Set DMA destination address */
849         hdac->DMA_Handle2->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = tmpreg;
850 
851         /* Enable the DMA channel */
852         status = HAL_DMAEx_List_Start_IT(hdac->DMA_Handle2);
853       }
854       else
855       {
856         /* Return error status */
857         return HAL_ERROR;
858       }
859     }
860     else
861     {
862       /* Length should be converted to number of bytes */
863       if (hdac->DMA_Handle2->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_WORD)
864       {
865         /* Word -> Bytes */
866         LengthInBytes = Length * 4U;
867       }
868       else if (hdac->DMA_Handle2->Init.SrcDataWidth == DMA_SRC_DATAWIDTH_HALFWORD)
869       {
870         /* Halfword -> Bytes */
871         LengthInBytes = Length * 2U;
872       }
873       else /* Bytes */
874       {
875         /* Same size already expressed in Bytes */
876         LengthInBytes = Length;
877       }
878 
879       /* Enable the DMA channel */
880       status = HAL_DMA_Start_IT(hdac->DMA_Handle2, (uint32_t)pData, tmpreg, LengthInBytes);
881     }
882   }
883 
884 
885   /* Process Unlocked */
886   __HAL_UNLOCK(hdac);
887 
888   if (status == HAL_OK)
889   {
890     /* Enable the Peripheral */
891     __HAL_DAC_ENABLE(hdac, Channel);
892     /* Ensure minimum wait before using peripheral after enabling it */
893     /* Wait loop initialization and execution */
894     /* Note: Variable divided by 2 to compensate partially              */
895     /*       CPU processing cycles, scaling in us split to not          */
896     /*       exceed 32 bits register capacity and handle low frequency. */
897     wait_loop_index = ((DAC_DELAY_STARTUP_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
898     while(wait_loop_index != 0UL)
899     {
900       wait_loop_index--;
901     }
902   }
903   else
904   {
905     hdac->ErrorCode |= HAL_DAC_ERROR_DMA;
906   }
907 
908   /* Return function status */
909   return status;
910 }
911 
912 /**
913   * @brief  Disables DAC and stop conversion of channel.
914   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
915   *         the configuration information for the specified DAC.
916   * @param  Channel The selected DAC channel.
917   *          This parameter can be one of the following values:
918   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
919   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
920   * @retval HAL status
921   */
HAL_DAC_Stop_DMA(DAC_HandleTypeDef * hdac,uint32_t Channel)922 HAL_StatusTypeDef HAL_DAC_Stop_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel)
923 {
924   /* Check the DAC peripheral handle */
925   if (hdac == NULL)
926   {
927     return HAL_ERROR;
928   }
929 
930   /* Check the parameters */
931   assert_param(IS_DAC_CHANNEL(Channel));
932 
933   /* Disable the selected DAC channel DMA request */
934   hdac->Instance->CR &= ~(DAC_CR_DMAEN1 << (Channel & 0x10UL));
935 
936   /* Disable the Peripheral */
937   __HAL_DAC_DISABLE(hdac, Channel);
938 
939   /* Disable the DMA channel */
940 
941   /* Channel1 is used */
942   if (Channel == DAC_CHANNEL_1)
943   {
944     /* Disable the DMA channel */
945     (void)HAL_DMA_Abort(hdac->DMA_Handle1);
946 
947     /* Disable the DAC DMA underrun interrupt */
948     __HAL_DAC_DISABLE_IT(hdac, DAC_IT_DMAUDR1);
949   }
950 
951   else /* Channel2 is used for */
952   {
953     /* Disable the DMA channel */
954     (void)HAL_DMA_Abort(hdac->DMA_Handle2);
955 
956     /* Disable the DAC DMA underrun interrupt */
957     __HAL_DAC_DISABLE_IT(hdac, DAC_IT_DMAUDR2);
958   }
959 
960 
961   /* Change DAC state */
962   hdac->State = HAL_DAC_STATE_READY;
963 
964   /* Return function status */
965   return HAL_OK;
966 }
967 
968 /**
969   * @brief  Handles DAC interrupt request
970   *         This function uses the interruption of DMA
971   *         underrun.
972   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
973   *         the configuration information for the specified DAC.
974   * @retval None
975   */
HAL_DAC_IRQHandler(DAC_HandleTypeDef * hdac)976 void HAL_DAC_IRQHandler(DAC_HandleTypeDef *hdac)
977 {
978   uint32_t itsource = hdac->Instance->CR;
979   uint32_t itflag   = hdac->Instance->SR;
980 
981   if ((itsource & DAC_IT_DMAUDR1) == DAC_IT_DMAUDR1)
982   {
983     /* Check underrun flag of DAC channel 1 */
984     if ((itflag & DAC_FLAG_DMAUDR1) == DAC_FLAG_DMAUDR1)
985     {
986       /* Change DAC state to error state */
987       hdac->State = HAL_DAC_STATE_ERROR;
988 
989       /* Set DAC error code to channel1 DMA underrun error */
990       SET_BIT(hdac->ErrorCode, HAL_DAC_ERROR_DMAUNDERRUNCH1);
991 
992       /* Clear the underrun flag */
993       __HAL_DAC_CLEAR_FLAG(hdac, DAC_FLAG_DMAUDR1);
994 
995       /* Disable the selected DAC channel1 DMA request */
996       __HAL_DAC_DISABLE_IT(hdac, DAC_CR_DMAEN1);
997 
998       /* Error callback */
999 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
1000       hdac->DMAUnderrunCallbackCh1(hdac);
1001 #else
1002       HAL_DAC_DMAUnderrunCallbackCh1(hdac);
1003 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
1004     }
1005   }
1006 
1007 
1008   if ((itsource & DAC_IT_DMAUDR2) == DAC_IT_DMAUDR2)
1009   {
1010     /* Check underrun flag of DAC channel 2 */
1011     if ((itflag & DAC_FLAG_DMAUDR2) == DAC_FLAG_DMAUDR2)
1012     {
1013       /* Change DAC state to error state */
1014       hdac->State = HAL_DAC_STATE_ERROR;
1015 
1016       /* Set DAC error code to channel2 DMA underrun error */
1017       SET_BIT(hdac->ErrorCode, HAL_DAC_ERROR_DMAUNDERRUNCH2);
1018 
1019       /* Clear the underrun flag */
1020       __HAL_DAC_CLEAR_FLAG(hdac, DAC_FLAG_DMAUDR2);
1021 
1022       /* Disable the selected DAC channel2 DMA request */
1023       __HAL_DAC_DISABLE_IT(hdac, DAC_CR_DMAEN2);
1024 
1025       /* Error callback */
1026 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
1027       hdac->DMAUnderrunCallbackCh2(hdac);
1028 #else
1029       HAL_DACEx_DMAUnderrunCallbackCh2(hdac);
1030 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
1031     }
1032   }
1033 
1034 }
1035 
1036 /**
1037   * @brief  Set the specified data holding register value for DAC channel.
1038   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
1039   *         the configuration information for the specified DAC.
1040   * @param  Channel The selected DAC channel.
1041   *          This parameter can be one of the following values:
1042   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
1043   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
1044   * @param  Alignment Specifies the data alignment.
1045   *          This parameter can be one of the following values:
1046   *            @arg DAC_ALIGN_8B_R: 8bit right data alignment selected
1047   *            @arg DAC_ALIGN_12B_L: 12bit left data alignment selected
1048   *            @arg DAC_ALIGN_12B_R: 12bit right data alignment selected
1049   * @param  Data Data to be loaded in the selected data holding register.
1050   * @retval HAL status
1051   */
HAL_DAC_SetValue(DAC_HandleTypeDef * hdac,uint32_t Channel,uint32_t Alignment,uint32_t Data)1052 HAL_StatusTypeDef HAL_DAC_SetValue(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data)
1053 {
1054   __IO uint32_t tmp = 0UL;
1055 
1056   /* Check the DAC peripheral handle */
1057   if (hdac == NULL)
1058   {
1059     return HAL_ERROR;
1060   }
1061 
1062   /* Check the parameters */
1063   assert_param(IS_DAC_CHANNEL(Channel));
1064   assert_param(IS_DAC_ALIGN(Alignment));
1065   /* In case DMA Double data mode is activated, DATA range is almost full uin32_t one: no check */
1066   if ((hdac->Instance->MCR & (DAC_MCR_DMADOUBLE1 << (Channel & 0x10UL))) == 0UL)
1067   {
1068     assert_param(IS_DAC_DATA(Data));
1069   }
1070 
1071   tmp = (uint32_t)hdac->Instance;
1072   if (Channel == DAC_CHANNEL_1)
1073   {
1074     tmp += DAC_DHR12R1_ALIGNMENT(Alignment);
1075   }
1076 
1077   else
1078   {
1079     tmp += DAC_DHR12R2_ALIGNMENT(Alignment);
1080   }
1081 
1082 
1083   /* Set the DAC channel selected data holding register */
1084   *(__IO uint32_t *) tmp = Data;
1085 
1086   /* Return function status */
1087   return HAL_OK;
1088 }
1089 
1090 /**
1091   * @brief  Conversion complete callback in non-blocking mode for Channel1
1092   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
1093   *         the configuration information for the specified DAC.
1094   * @retval None
1095   */
HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef * hdac)1096 __weak void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef *hdac)
1097 {
1098   /* Prevent unused argument(s) compilation warning */
1099   UNUSED(hdac);
1100 
1101   /* NOTE : This function should not be modified, when the callback is needed,
1102             the HAL_DAC_ConvCpltCallbackCh1 could be implemented in the user file
1103    */
1104 }
1105 
1106 /**
1107   * @brief  Conversion half DMA transfer callback in non-blocking mode for Channel1
1108   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
1109   *         the configuration information for the specified DAC.
1110   * @retval None
1111   */
HAL_DAC_ConvHalfCpltCallbackCh1(DAC_HandleTypeDef * hdac)1112 __weak void HAL_DAC_ConvHalfCpltCallbackCh1(DAC_HandleTypeDef *hdac)
1113 {
1114   /* Prevent unused argument(s) compilation warning */
1115   UNUSED(hdac);
1116 
1117   /* NOTE : This function should not be modified, when the callback is needed,
1118             the HAL_DAC_ConvHalfCpltCallbackCh1 could be implemented in the user file
1119    */
1120 }
1121 
1122 /**
1123   * @brief  Error DAC callback for Channel1.
1124   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
1125   *         the configuration information for the specified DAC.
1126   * @retval None
1127   */
HAL_DAC_ErrorCallbackCh1(DAC_HandleTypeDef * hdac)1128 __weak void HAL_DAC_ErrorCallbackCh1(DAC_HandleTypeDef *hdac)
1129 {
1130   /* Prevent unused argument(s) compilation warning */
1131   UNUSED(hdac);
1132 
1133   /* NOTE : This function should not be modified, when the callback is needed,
1134             the HAL_DAC_ErrorCallbackCh1 could be implemented in the user file
1135    */
1136 }
1137 
1138 /**
1139   * @brief  DMA underrun DAC callback for channel1.
1140   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
1141   *         the configuration information for the specified DAC.
1142   * @retval None
1143   */
HAL_DAC_DMAUnderrunCallbackCh1(DAC_HandleTypeDef * hdac)1144 __weak void HAL_DAC_DMAUnderrunCallbackCh1(DAC_HandleTypeDef *hdac)
1145 {
1146   /* Prevent unused argument(s) compilation warning */
1147   UNUSED(hdac);
1148 
1149   /* NOTE : This function should not be modified, when the callback is needed,
1150             the HAL_DAC_DMAUnderrunCallbackCh1 could be implemented in the user file
1151    */
1152 }
1153 
1154 /**
1155   * @}
1156   */
1157 
1158 /** @defgroup DAC_Exported_Functions_Group3 Peripheral Control functions
1159   *  @brief    Peripheral Control functions
1160   *
1161 @verbatim
1162   ==============================================================================
1163              ##### Peripheral Control functions #####
1164   ==============================================================================
1165     [..]  This section provides functions allowing to:
1166       (+) Configure channels.
1167       (+) Set the specified data holding register value for DAC channel.
1168 
1169 @endverbatim
1170   * @{
1171   */
1172 
1173 /**
1174   * @brief  Returns the last data output value of the selected DAC channel.
1175   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
1176   *         the configuration information for the specified DAC.
1177   * @param  Channel The selected DAC channel.
1178   *          This parameter can be one of the following values:
1179   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
1180   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
1181   * @retval The selected DAC channel data output value.
1182   */
HAL_DAC_GetValue(const DAC_HandleTypeDef * hdac,uint32_t Channel)1183 uint32_t HAL_DAC_GetValue(const DAC_HandleTypeDef *hdac, uint32_t Channel)
1184 {
1185   uint32_t result;
1186 
1187   /* Check the DAC peripheral handle */
1188   assert_param(hdac != NULL);
1189 
1190   /* Check the parameters */
1191   assert_param(IS_DAC_CHANNEL(Channel));
1192 
1193   if (Channel == DAC_CHANNEL_1)
1194   {
1195     result = hdac->Instance->DOR1;
1196   }
1197 
1198   else
1199   {
1200     result = hdac->Instance->DOR2;
1201   }
1202 
1203   /* Returns the DAC channel data output register value */
1204   return result;
1205 }
1206 
1207 /**
1208   * @brief  Configures the selected DAC channel.
1209   * @note   By calling this function, the high frequency interface mode (HFSEL bits)
1210   *         will be set. This parameter scope is the DAC instance. As the function
1211   *         is called for each channel, the @ref DAC_HighFrequency of @arg sConfig
1212   *         must be the same at each call.
1213   *         (or DAC_HIGH_FREQUENCY_INTERFACE_MODE_AUTOMATIC self detect).
1214   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
1215   *         the configuration information for the specified DAC.
1216   * @param  sConfig DAC configuration structure.
1217   * @param  Channel The selected DAC channel.
1218   *          This parameter can be one of the following values:
1219   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
1220   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
1221   * @retval HAL status
1222   */
HAL_DAC_ConfigChannel(DAC_HandleTypeDef * hdac,const DAC_ChannelConfTypeDef * sConfig,uint32_t Channel)1223 HAL_StatusTypeDef HAL_DAC_ConfigChannel(DAC_HandleTypeDef *hdac,
1224                                         const DAC_ChannelConfTypeDef *sConfig, uint32_t Channel)
1225 {
1226   HAL_StatusTypeDef status = HAL_OK;
1227   uint32_t tmpreg1;
1228   uint32_t tmpreg2;
1229   uint32_t tickstart;
1230   uint32_t hclkfreq;
1231   uint32_t connectOnChip;
1232 
1233   /* Check the DAC peripheral handle and channel configuration struct */
1234   if ((hdac == NULL) || (sConfig == NULL))
1235   {
1236     return HAL_ERROR;
1237   }
1238 
1239   /* Check the DAC parameters */
1240   assert_param(IS_DAC_HIGH_FREQUENCY_MODE(sConfig->DAC_HighFrequency));
1241   assert_param(IS_DAC_TRIGGER(sConfig->DAC_Trigger));
1242   assert_param(IS_DAC_OUTPUT_BUFFER_STATE(sConfig->DAC_OutputBuffer));
1243   assert_param(IS_DAC_CHIP_CONNECTION(sConfig->DAC_ConnectOnChipPeripheral));
1244   assert_param(IS_DAC_TRIMMING(sConfig->DAC_UserTrimming));
1245   if ((sConfig->DAC_UserTrimming) == DAC_TRIMMING_USER)
1246   {
1247     assert_param(IS_DAC_TRIMMINGVALUE(sConfig->DAC_TrimmingValue));
1248   }
1249   assert_param(IS_DAC_SAMPLEANDHOLD(sConfig->DAC_SampleAndHold));
1250   if ((sConfig->DAC_SampleAndHold) == DAC_SAMPLEANDHOLD_ENABLE)
1251   {
1252     assert_param(IS_DAC_SAMPLETIME(sConfig->DAC_SampleAndHoldConfig.DAC_SampleTime));
1253     assert_param(IS_DAC_HOLDTIME(sConfig->DAC_SampleAndHoldConfig.DAC_HoldTime));
1254     assert_param(IS_DAC_REFRESHTIME(sConfig->DAC_SampleAndHoldConfig.DAC_RefreshTime));
1255   }
1256   assert_param(IS_DAC_CHANNEL(Channel));
1257   assert_param(IS_FUNCTIONAL_STATE(sConfig->DAC_DMADoubleDataMode));
1258   assert_param(IS_FUNCTIONAL_STATE(sConfig->DAC_SignedFormat));
1259 
1260   /* Process locked */
1261   __HAL_LOCK(hdac);
1262 
1263   /* Change DAC state */
1264   hdac->State = HAL_DAC_STATE_BUSY;
1265 
1266   /* Sample and hold configuration */
1267   if (sConfig->DAC_SampleAndHold == DAC_SAMPLEANDHOLD_ENABLE)
1268   {
1269     /* Get timeout */
1270     tickstart = HAL_GetTick();
1271 
1272     if (Channel == DAC_CHANNEL_1)
1273     {
1274       /* SHSR1 can be written when BWST1 is cleared */
1275       while (((hdac->Instance->SR) & DAC_SR_BWST1) != 0UL)
1276       {
1277         /* Check for the Timeout */
1278         if ((HAL_GetTick() - tickstart) > TIMEOUT_DAC_CALIBCONFIG)
1279         {
1280           /* New check to avoid false timeout detection in case of preemption */
1281           if (((hdac->Instance->SR) & DAC_SR_BWST1) != 0UL)
1282           {
1283             /* Update error code */
1284             SET_BIT(hdac->ErrorCode, HAL_DAC_ERROR_TIMEOUT);
1285 
1286             /* Change the DMA state */
1287             hdac->State = HAL_DAC_STATE_TIMEOUT;
1288 
1289             return HAL_TIMEOUT;
1290           }
1291         }
1292       }
1293       hdac->Instance->SHSR1 = sConfig->DAC_SampleAndHoldConfig.DAC_SampleTime;
1294     }
1295 
1296     else /* Channel 2 */
1297     {
1298       /* SHSR2 can be written when BWST2 is cleared */
1299       while (((hdac->Instance->SR) & DAC_SR_BWST2) != 0UL)
1300       {
1301         /* Check for the Timeout */
1302         if ((HAL_GetTick() - tickstart) > TIMEOUT_DAC_CALIBCONFIG)
1303         {
1304           /* New check to avoid false timeout detection in case of preemption */
1305           if (((hdac->Instance->SR) & DAC_SR_BWST2) != 0UL)
1306           {
1307             /* Update error code */
1308             SET_BIT(hdac->ErrorCode, HAL_DAC_ERROR_TIMEOUT);
1309 
1310             /* Change the DMA state */
1311             hdac->State = HAL_DAC_STATE_TIMEOUT;
1312 
1313             return HAL_TIMEOUT;
1314           }
1315         }
1316       }
1317       hdac->Instance->SHSR2 = sConfig->DAC_SampleAndHoldConfig.DAC_SampleTime;
1318     }
1319 
1320 
1321     /* HoldTime */
1322     MODIFY_REG(hdac->Instance->SHHR, DAC_SHHR_THOLD1 << (Channel & 0x10UL),
1323                (sConfig->DAC_SampleAndHoldConfig.DAC_HoldTime) << (Channel & 0x10UL));
1324     /* RefreshTime */
1325     MODIFY_REG(hdac->Instance->SHRR, DAC_SHRR_TREFRESH1 << (Channel & 0x10UL),
1326                (sConfig->DAC_SampleAndHoldConfig.DAC_RefreshTime) << (Channel & 0x10UL));
1327   }
1328 
1329   if (sConfig->DAC_UserTrimming == DAC_TRIMMING_USER)
1330     /* USER TRIMMING */
1331   {
1332     /* Get the DAC CCR value */
1333     tmpreg1 = hdac->Instance->CCR;
1334     /* Clear trimming value */
1335     tmpreg1 &= ~(((uint32_t)(DAC_CCR_OTRIM1)) << (Channel & 0x10UL));
1336     /* Configure for the selected trimming offset */
1337     tmpreg2 = sConfig->DAC_TrimmingValue;
1338     /* Calculate CCR register value depending on DAC_Channel */
1339     tmpreg1 |= tmpreg2 << (Channel & 0x10UL);
1340     /* Write to DAC CCR */
1341     hdac->Instance->CCR = tmpreg1;
1342   }
1343   /* else factory trimming is used (factory setting are available at reset)*/
1344   /* SW Nothing has nothing to do */
1345 
1346   /* Get the DAC MCR value */
1347   tmpreg1 = hdac->Instance->MCR;
1348   /* Clear DAC_MCR_MODEx bits */
1349   tmpreg1 &= ~(((uint32_t)(DAC_MCR_MODE1)) << (Channel & 0x10UL));
1350   /* Configure for the selected DAC channel: mode, buffer output & on chip peripheral connect */
1351 
1352 #if !defined(TIM8)
1353 /* Devices STM32H503xx */
1354   /* On STM32H503EB (package WLCSP25) DAC channel 1 connection to GPIO is not available and should not be configured.
1355      Package information is stored at the address PACKAGE_BASE, WLCSP25 correspond to the value 0xF (For more
1356      information, please refer to the Reference Manual) */
1357   __IO uint32_t* tmp_package = (uint32_t*)PACKAGE_BASE;
1358   if ( (*(tmp_package) & 0x1FUL) == 0x0FUL)
1359   {
1360     if ( (Channel == DAC_CHANNEL_1)
1361       && ( (sConfig->DAC_ConnectOnChipPeripheral == DAC_CHIPCONNECT_EXTERNAL)
1362          || (sConfig->DAC_ConnectOnChipPeripheral == DAC_CHIPCONNECT_BOTH)) )
1363       {
1364         /* Update return status */
1365         status = HAL_ERROR;
1366 
1367         /* Change the DAC state */
1368         hdac->State = HAL_DAC_STATE_ERROR;
1369 
1370         /* Update error code */
1371         SET_BIT(hdac->ErrorCode, HAL_DAC_ERROR_INVALID_CONFIG);
1372       }
1373   }
1374 #endif /* Devices STM32H503xx */
1375 
1376 
1377   if (sConfig->DAC_ConnectOnChipPeripheral == DAC_CHIPCONNECT_EXTERNAL)
1378   {
1379     connectOnChip = 0x00000000UL;
1380   }
1381   else if (sConfig->DAC_ConnectOnChipPeripheral == DAC_CHIPCONNECT_INTERNAL)
1382   {
1383     connectOnChip = DAC_MCR_MODE1_0;
1384   }
1385   else /* (sConfig->DAC_ConnectOnChipPeripheral == DAC_CHIPCONNECT_BOTH) */
1386   {
1387     if (sConfig->DAC_OutputBuffer == DAC_OUTPUTBUFFER_ENABLE)
1388     {
1389       connectOnChip = DAC_MCR_MODE1_0;
1390     }
1391     else
1392     {
1393       connectOnChip = 0x00000000UL;
1394     }
1395   }
1396   tmpreg2 = (sConfig->DAC_SampleAndHold | sConfig->DAC_OutputBuffer | connectOnChip);
1397   /* Clear DAC_MCR_DMADOUBLEx */
1398   tmpreg1 &= ~(((uint32_t)(DAC_MCR_DMADOUBLE1)) << (Channel & 0x10UL));
1399   /* Configure for the selected DAC channel: DMA double data mode */
1400   tmpreg2 |= (sConfig->DAC_DMADoubleDataMode == ENABLE) ? DAC_MCR_DMADOUBLE1 : 0UL;
1401   /* Clear DAC_MCR_SINFORMATx */
1402   tmpreg1 &= ~(((uint32_t)(DAC_MCR_SINFORMAT1)) << (Channel & 0x10UL));
1403   /* Configure for the selected DAC channel: Signed format */
1404   tmpreg2 |= (sConfig->DAC_SignedFormat == ENABLE) ? DAC_MCR_SINFORMAT1 : 0UL;
1405   /* Clear DAC_MCR_HFSEL bits */
1406   tmpreg1 &= ~(DAC_MCR_HFSEL);
1407   /* Configure for both DAC channels: high frequency mode */
1408   if (DAC_HIGH_FREQUENCY_INTERFACE_MODE_AUTOMATIC == sConfig->DAC_HighFrequency)
1409   {
1410     hclkfreq = HAL_RCC_GetHCLKFreq();
1411     if (hclkfreq > HFSEL_ENABLE_THRESHOLD_160MHZ)
1412     {
1413       tmpreg1 |= DAC_HIGH_FREQUENCY_INTERFACE_MODE_ABOVE_160MHZ;
1414     }
1415     else if (hclkfreq > HFSEL_ENABLE_THRESHOLD_80MHZ)
1416     {
1417       tmpreg1 |= DAC_HIGH_FREQUENCY_INTERFACE_MODE_ABOVE_80MHZ;
1418     }
1419     else
1420     {
1421       tmpreg1 |= DAC_HIGH_FREQUENCY_INTERFACE_MODE_DISABLE;
1422     }
1423   }
1424   else
1425   {
1426     tmpreg1 |= sConfig->DAC_HighFrequency;
1427   }
1428   /* Calculate MCR register value depending on DAC_Channel */
1429   tmpreg1 |= tmpreg2 << (Channel & 0x10UL);
1430   /* Write to DAC MCR */
1431   hdac->Instance->MCR = tmpreg1;
1432 
1433   /* DAC in normal operating mode hence clear DAC_CR_CENx bit */
1434   CLEAR_BIT(hdac->Instance->CR, DAC_CR_CEN1 << (Channel & 0x10UL));
1435 
1436   /* Get the DAC CR value */
1437   tmpreg1 = hdac->Instance->CR;
1438   /* Clear TENx, TSELx, WAVEx and MAMPx bits */
1439   tmpreg1 &= ~(((uint32_t)(DAC_CR_MAMP1 | DAC_CR_WAVE1 | DAC_CR_TSEL1 | DAC_CR_TEN1)) << (Channel & 0x10UL));
1440   /* Configure for the selected DAC channel: trigger */
1441   /* Set TSELx and TENx bits according to DAC_Trigger value */
1442   tmpreg2 = sConfig->DAC_Trigger;
1443   /* Calculate CR register value depending on DAC_Channel */
1444   tmpreg1 |= tmpreg2 << (Channel & 0x10UL);
1445   /* Write to DAC CR */
1446   hdac->Instance->CR = tmpreg1;
1447   /* Disable wave generation */
1448   CLEAR_BIT(hdac->Instance->CR, (DAC_CR_WAVE1 << (Channel & 0x10UL)));
1449 
1450   /* Change DAC state */
1451   hdac->State = HAL_DAC_STATE_READY;
1452 
1453   /* Process unlocked */
1454   __HAL_UNLOCK(hdac);
1455 
1456   /* Return function status */
1457   return status;
1458 }
1459 
1460 /**
1461   * @}
1462   */
1463 
1464 /** @defgroup DAC_Exported_Functions_Group4 Peripheral State and Errors functions
1465   *  @brief   Peripheral State and Errors functions
1466   *
1467 @verbatim
1468   ==============================================================================
1469             ##### Peripheral State and Errors functions #####
1470   ==============================================================================
1471     [..]
1472     This subsection provides functions allowing to
1473       (+) Check the DAC state.
1474       (+) Check the DAC Errors.
1475 
1476 @endverbatim
1477   * @{
1478   */
1479 
1480 /**
1481   * @brief  return the DAC handle state
1482   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
1483   *         the configuration information for the specified DAC.
1484   * @retval HAL state
1485   */
HAL_DAC_GetState(const DAC_HandleTypeDef * hdac)1486 HAL_DAC_StateTypeDef HAL_DAC_GetState(const DAC_HandleTypeDef *hdac)
1487 {
1488   /* Return DAC handle state */
1489   return hdac->State;
1490 }
1491 
1492 
1493 /**
1494   * @brief  Return the DAC error code
1495   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
1496   *         the configuration information for the specified DAC.
1497   * @retval DAC Error Code
1498   */
HAL_DAC_GetError(const DAC_HandleTypeDef * hdac)1499 uint32_t HAL_DAC_GetError(const DAC_HandleTypeDef *hdac)
1500 {
1501   return hdac->ErrorCode;
1502 }
1503 
1504 /**
1505   * @}
1506   */
1507 
1508 /**
1509   * @}
1510   */
1511 
1512 /** @addtogroup DAC_Exported_Functions
1513   * @{
1514   */
1515 
1516 /** @addtogroup DAC_Exported_Functions_Group1
1517   * @{
1518   */
1519 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
1520 /**
1521   * @brief  Register a User DAC Callback
1522   *         To be used instead of the weak (surcharged) predefined callback
1523   * @note   The HAL_DAC_RegisterCallback() may be called before HAL_DAC_Init() in HAL_DAC_STATE_RESET to register
1524   *         callbacks for HAL_DAC_MSPINIT_CB_ID and HAL_DAC_MSPDEINIT_CB_ID
1525   * @param  hdac DAC handle
1526   * @param  CallbackID ID of the callback to be registered
1527   *         This parameter can be one of the following values:
1528   *          @arg @ref HAL_DAC_ERROR_INVALID_CALLBACK   DAC Error Callback ID
1529   *          @arg @ref HAL_DAC_CH1_COMPLETE_CB_ID       DAC CH1 Complete Callback ID
1530   *          @arg @ref HAL_DAC_CH1_HALF_COMPLETE_CB_ID  DAC CH1 Half Complete Callback ID
1531   *          @arg @ref HAL_DAC_CH1_ERROR_ID             DAC CH1 Error Callback ID
1532   *          @arg @ref HAL_DAC_CH1_UNDERRUN_CB_ID       DAC CH1 UnderRun Callback ID
1533   *          @arg @ref HAL_DAC_CH2_COMPLETE_CB_ID       DAC CH2 Complete Callback ID
1534   *          @arg @ref HAL_DAC_CH2_HALF_COMPLETE_CB_ID  DAC CH2 Half Complete Callback ID
1535   *          @arg @ref HAL_DAC_CH2_ERROR_ID             DAC CH2 Error Callback ID
1536   *          @arg @ref HAL_DAC_CH2_UNDERRUN_CB_ID       DAC CH2 UnderRun Callback ID
1537   *          @arg @ref HAL_DAC_MSPINIT_CB_ID            DAC MSP Init Callback ID
1538   *          @arg @ref HAL_DAC_MSPDEINIT_CB_ID          DAC MSP DeInit Callback ID
1539   *
1540   * @param  pCallback pointer to the Callback function
1541   * @retval status
1542   */
HAL_DAC_RegisterCallback(DAC_HandleTypeDef * hdac,HAL_DAC_CallbackIDTypeDef CallbackID,pDAC_CallbackTypeDef pCallback)1543 HAL_StatusTypeDef HAL_DAC_RegisterCallback(DAC_HandleTypeDef *hdac, HAL_DAC_CallbackIDTypeDef CallbackID,
1544                                            pDAC_CallbackTypeDef pCallback)
1545 {
1546   HAL_StatusTypeDef status = HAL_OK;
1547 
1548   /* Check the DAC peripheral handle */
1549   if (hdac == NULL)
1550   {
1551     return HAL_ERROR;
1552   }
1553 
1554   if (pCallback == NULL)
1555   {
1556     /* Update the error code */
1557     hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK;
1558     return HAL_ERROR;
1559   }
1560 
1561   if (hdac->State == HAL_DAC_STATE_READY)
1562   {
1563     switch (CallbackID)
1564     {
1565       case HAL_DAC_CH1_COMPLETE_CB_ID :
1566         hdac->ConvCpltCallbackCh1 = pCallback;
1567         break;
1568       case HAL_DAC_CH1_HALF_COMPLETE_CB_ID :
1569         hdac->ConvHalfCpltCallbackCh1 = pCallback;
1570         break;
1571       case HAL_DAC_CH1_ERROR_ID :
1572         hdac->ErrorCallbackCh1 = pCallback;
1573         break;
1574       case HAL_DAC_CH1_UNDERRUN_CB_ID :
1575         hdac->DMAUnderrunCallbackCh1 = pCallback;
1576         break;
1577 
1578       case HAL_DAC_CH2_COMPLETE_CB_ID :
1579         hdac->ConvCpltCallbackCh2 = pCallback;
1580         break;
1581       case HAL_DAC_CH2_HALF_COMPLETE_CB_ID :
1582         hdac->ConvHalfCpltCallbackCh2 = pCallback;
1583         break;
1584       case HAL_DAC_CH2_ERROR_ID :
1585         hdac->ErrorCallbackCh2 = pCallback;
1586         break;
1587       case HAL_DAC_CH2_UNDERRUN_CB_ID :
1588         hdac->DMAUnderrunCallbackCh2 = pCallback;
1589         break;
1590 
1591       case HAL_DAC_MSPINIT_CB_ID :
1592         hdac->MspInitCallback = pCallback;
1593         break;
1594       case HAL_DAC_MSPDEINIT_CB_ID :
1595         hdac->MspDeInitCallback = pCallback;
1596         break;
1597       default :
1598         /* Update the error code */
1599         hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK;
1600         /* update return status */
1601         status =  HAL_ERROR;
1602         break;
1603     }
1604   }
1605   else if (hdac->State == HAL_DAC_STATE_RESET)
1606   {
1607     switch (CallbackID)
1608     {
1609       case HAL_DAC_MSPINIT_CB_ID :
1610         hdac->MspInitCallback = pCallback;
1611         break;
1612       case HAL_DAC_MSPDEINIT_CB_ID :
1613         hdac->MspDeInitCallback = pCallback;
1614         break;
1615       default :
1616         /* Update the error code */
1617         hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK;
1618         /* update return status */
1619         status =  HAL_ERROR;
1620         break;
1621     }
1622   }
1623   else
1624   {
1625     /* Update the error code */
1626     hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK;
1627     /* update return status */
1628     status =  HAL_ERROR;
1629   }
1630 
1631   return status;
1632 }
1633 
1634 /**
1635   * @brief  Unregister a User DAC Callback
1636   *         DAC Callback is redirected to the weak (surcharged) predefined callback
1637   * @note   The HAL_DAC_UnRegisterCallback() may be called before HAL_DAC_Init() in HAL_DAC_STATE_RESET to un-register
1638   *         callbacks for HAL_DAC_MSPINIT_CB_ID and HAL_DAC_MSPDEINIT_CB_ID
1639   * @param  hdac DAC handle
1640   * @param  CallbackID ID of the callback to be unregistered
1641   *         This parameter can be one of the following values:
1642   *          @arg @ref HAL_DAC_CH1_COMPLETE_CB_ID          DAC CH1 transfer Complete Callback ID
1643   *          @arg @ref HAL_DAC_CH1_HALF_COMPLETE_CB_ID     DAC CH1 Half Complete Callback ID
1644   *          @arg @ref HAL_DAC_CH1_ERROR_ID                DAC CH1 Error Callback ID
1645   *          @arg @ref HAL_DAC_CH1_UNDERRUN_CB_ID          DAC CH1 UnderRun Callback ID
1646   *          @arg @ref HAL_DAC_CH2_COMPLETE_CB_ID          DAC CH2 Complete Callback ID
1647   *          @arg @ref HAL_DAC_CH2_HALF_COMPLETE_CB_ID     DAC CH2 Half Complete Callback ID
1648   *          @arg @ref HAL_DAC_CH2_ERROR_ID                DAC CH2 Error Callback ID
1649   *          @arg @ref HAL_DAC_CH2_UNDERRUN_CB_ID          DAC CH2 UnderRun Callback ID
1650   *          @arg @ref HAL_DAC_MSPINIT_CB_ID               DAC MSP Init Callback ID
1651   *          @arg @ref HAL_DAC_MSPDEINIT_CB_ID             DAC MSP DeInit Callback ID
1652   *          @arg @ref HAL_DAC_ALL_CB_ID                   DAC All callbacks
1653   * @retval status
1654   */
HAL_DAC_UnRegisterCallback(DAC_HandleTypeDef * hdac,HAL_DAC_CallbackIDTypeDef CallbackID)1655 HAL_StatusTypeDef HAL_DAC_UnRegisterCallback(DAC_HandleTypeDef *hdac, HAL_DAC_CallbackIDTypeDef CallbackID)
1656 {
1657   HAL_StatusTypeDef status = HAL_OK;
1658 
1659   /* Check the DAC peripheral handle */
1660   if (hdac == NULL)
1661   {
1662     return HAL_ERROR;
1663   }
1664 
1665   if (hdac->State == HAL_DAC_STATE_READY)
1666   {
1667     switch (CallbackID)
1668     {
1669       case HAL_DAC_CH1_COMPLETE_CB_ID :
1670         hdac->ConvCpltCallbackCh1 = HAL_DAC_ConvCpltCallbackCh1;
1671         break;
1672       case HAL_DAC_CH1_HALF_COMPLETE_CB_ID :
1673         hdac->ConvHalfCpltCallbackCh1 = HAL_DAC_ConvHalfCpltCallbackCh1;
1674         break;
1675       case HAL_DAC_CH1_ERROR_ID :
1676         hdac->ErrorCallbackCh1 = HAL_DAC_ErrorCallbackCh1;
1677         break;
1678       case HAL_DAC_CH1_UNDERRUN_CB_ID :
1679         hdac->DMAUnderrunCallbackCh1 = HAL_DAC_DMAUnderrunCallbackCh1;
1680         break;
1681 
1682       case HAL_DAC_CH2_COMPLETE_CB_ID :
1683         hdac->ConvCpltCallbackCh2 = HAL_DACEx_ConvCpltCallbackCh2;
1684         break;
1685       case HAL_DAC_CH2_HALF_COMPLETE_CB_ID :
1686         hdac->ConvHalfCpltCallbackCh2 = HAL_DACEx_ConvHalfCpltCallbackCh2;
1687         break;
1688       case HAL_DAC_CH2_ERROR_ID :
1689         hdac->ErrorCallbackCh2 = HAL_DACEx_ErrorCallbackCh2;
1690         break;
1691       case HAL_DAC_CH2_UNDERRUN_CB_ID :
1692         hdac->DMAUnderrunCallbackCh2 = HAL_DACEx_DMAUnderrunCallbackCh2;
1693         break;
1694 
1695       case HAL_DAC_MSPINIT_CB_ID :
1696         hdac->MspInitCallback = HAL_DAC_MspInit;
1697         break;
1698       case HAL_DAC_MSPDEINIT_CB_ID :
1699         hdac->MspDeInitCallback = HAL_DAC_MspDeInit;
1700         break;
1701       case HAL_DAC_ALL_CB_ID :
1702         hdac->ConvCpltCallbackCh1 = HAL_DAC_ConvCpltCallbackCh1;
1703         hdac->ConvHalfCpltCallbackCh1 = HAL_DAC_ConvHalfCpltCallbackCh1;
1704         hdac->ErrorCallbackCh1 = HAL_DAC_ErrorCallbackCh1;
1705         hdac->DMAUnderrunCallbackCh1 = HAL_DAC_DMAUnderrunCallbackCh1;
1706 
1707         hdac->ConvCpltCallbackCh2 = HAL_DACEx_ConvCpltCallbackCh2;
1708         hdac->ConvHalfCpltCallbackCh2 = HAL_DACEx_ConvHalfCpltCallbackCh2;
1709         hdac->ErrorCallbackCh2 = HAL_DACEx_ErrorCallbackCh2;
1710         hdac->DMAUnderrunCallbackCh2 = HAL_DACEx_DMAUnderrunCallbackCh2;
1711 
1712         hdac->MspInitCallback = HAL_DAC_MspInit;
1713         hdac->MspDeInitCallback = HAL_DAC_MspDeInit;
1714         break;
1715       default :
1716         /* Update the error code */
1717         hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK;
1718         /* update return status */
1719         status =  HAL_ERROR;
1720         break;
1721     }
1722   }
1723   else if (hdac->State == HAL_DAC_STATE_RESET)
1724   {
1725     switch (CallbackID)
1726     {
1727       case HAL_DAC_MSPINIT_CB_ID :
1728         hdac->MspInitCallback = HAL_DAC_MspInit;
1729         break;
1730       case HAL_DAC_MSPDEINIT_CB_ID :
1731         hdac->MspDeInitCallback = HAL_DAC_MspDeInit;
1732         break;
1733       default :
1734         /* Update the error code */
1735         hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK;
1736         /* update return status */
1737         status =  HAL_ERROR;
1738         break;
1739     }
1740   }
1741   else
1742   {
1743     /* Update the error code */
1744     hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK;
1745     /* update return status */
1746     status =  HAL_ERROR;
1747   }
1748 
1749   return status;
1750 }
1751 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
1752 
1753 /**
1754   * @}
1755   */
1756 
1757 /**
1758   * @}
1759   */
1760 
1761 /** @addtogroup DAC_Private_Functions
1762   * @{
1763   */
1764 
1765 /**
1766   * @brief  DMA conversion complete callback.
1767   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1768   *                the configuration information for the specified DMA module.
1769   * @retval None
1770   */
DAC_DMAConvCpltCh1(DMA_HandleTypeDef * hdma)1771 void DAC_DMAConvCpltCh1(DMA_HandleTypeDef *hdma)
1772 {
1773   DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1774 
1775 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
1776   hdac->ConvCpltCallbackCh1(hdac);
1777 #else
1778   HAL_DAC_ConvCpltCallbackCh1(hdac);
1779 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
1780 
1781   hdac->State = HAL_DAC_STATE_READY;
1782 }
1783 
1784 /**
1785   * @brief  DMA half transfer complete callback.
1786   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1787   *                the configuration information for the specified DMA module.
1788   * @retval None
1789   */
DAC_DMAHalfConvCpltCh1(DMA_HandleTypeDef * hdma)1790 void DAC_DMAHalfConvCpltCh1(DMA_HandleTypeDef *hdma)
1791 {
1792   DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1793   /* Conversion complete callback */
1794 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
1795   hdac->ConvHalfCpltCallbackCh1(hdac);
1796 #else
1797   HAL_DAC_ConvHalfCpltCallbackCh1(hdac);
1798 #endif  /* USE_HAL_DAC_REGISTER_CALLBACKS */
1799 }
1800 
1801 /**
1802   * @brief  DMA error callback
1803   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1804   *                the configuration information for the specified DMA module.
1805   * @retval None
1806   */
DAC_DMAErrorCh1(DMA_HandleTypeDef * hdma)1807 void DAC_DMAErrorCh1(DMA_HandleTypeDef *hdma)
1808 {
1809   DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1810 
1811   /* Set DAC error code to DMA error */
1812   hdac->ErrorCode |= HAL_DAC_ERROR_DMA;
1813 
1814 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
1815   hdac->ErrorCallbackCh1(hdac);
1816 #else
1817   HAL_DAC_ErrorCallbackCh1(hdac);
1818 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
1819 
1820   hdac->State = HAL_DAC_STATE_READY;
1821 }
1822 
1823 /**
1824   * @}
1825   */
1826 
1827 /**
1828   * @}
1829   */
1830 
1831 #endif /* DAC1 */
1832 
1833 #endif /* HAL_DAC_MODULE_ENABLED */
1834 /**
1835   * @}
1836   */
1837