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