1 /**
2   ******************************************************************************
3   * @file    stm32u0xx_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   #error "Please implement comment here for your STM32 series"
34       *** DAC Buffer mode feature ***
35       ===============================
36       [..]
37       Each DAC channel integrates an output buffer that can be used to
38       reduce the output impedance, and to drive external loads directly
39       without having to add an external operational amplifier.
40       To enable, the output buffer use
41       sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
42       [..]
43       (@) Refer to the device datasheet for more details about output
44           impedance value with and without output buffer.
45 
46       *** GPIO configurations guidelines ***
47       =====================
48       [..]
49       When a DAC channel is used (ex channel1 on PA4) and the other is not
50       (ex channel2 on PA5 is configured in Analog and disabled).
51       Channel1 may disturb channel2 as coupling effect.
52       Note that there is no coupling on channel2 as soon as channel2 is turned on.
53       Coupling on adjacent channel could be avoided as follows:
54       when unused PA5 is configured as INPUT PULL-UP or DOWN.
55       PA5 is configured in ANALOG just before it is turned on.
56 
57       *** DAC Sample and Hold feature ***
58       ========================
59       [..]
60       For each converter, 2 modes are supported: normal mode and
61       "sample and hold" mode (i.e. low power mode).
62       In the sample and hold mode, the DAC core converts data, then holds the
63       converted voltage on a capacitor. When not converting, the DAC cores and
64       buffer are completely turned off between samples and the DAC output is
65       tri-stated, therefore  reducing the overall power consumption. A new
66       stabilization period is needed before each new conversion.
67 
68       The sample and hold allow setting internal or external voltage @
69       low power consumption cost (output value can be at any given rate either
70       by CPU or DMA).
71 
72       The Sample and hold block and registers uses either LSI & run in
73       several power modes: run mode, sleep mode, low power run, low power sleep
74       mode & stop1 mode.
75 
76       Low power stop1 mode allows only static conversion.
77 
78       To enable Sample and Hold mode
79       Enable LSI using HAL_RCC_OscConfig with RCC_OSCILLATORTYPE_LSI &
80       RCC_LSI_ON parameters.
81 
82       Use DAC_InitStructure.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_ENABLE;
83          & DAC_ChannelConfTypeDef.DAC_SampleAndHoldConfig.DAC_SampleTime,
84            DAC_HoldTime & DAC_RefreshTime;
85 
86        *** DAC calibration feature ***
87        ===================================
88       [..]
89        (#)  The 2 converters (channel1 & channel2) provide calibration capabilities.
90        (++) Calibration aims at correcting some offset of output buffer.
91        (++) The DAC uses either factory calibration settings OR user defined
92            calibration (trimming) settings (i.e. trimming mode).
93        (++) The user defined settings can be figured out using self calibration
94            handled by HAL_DACEx_SelfCalibrate.
95        (++) HAL_DACEx_SelfCalibrate:
96        (+++) Runs automatically the calibration.
97        (+++) Enables the user trimming mode
98        (+++) Updates a structure with trimming values with fresh calibration
99             results.
100             The user may store the calibration results for larger
101             (ex monitoring the trimming as a function of temperature
102             for instance)
103 
104        *** DAC wave generation feature ***
105        ===================================
106        [..]
107        Both DAC channels can be used to generate
108          (#) Noise wave
109          (#) Triangle wave
110 
111        *** DAC data format ***
112        =======================
113        [..]
114        The DAC data format can be:
115          (#) 8-bit right alignment using DAC_ALIGN_8B_R
116          (#) 12-bit left alignment using DAC_ALIGN_12B_L
117          (#) 12-bit right alignment using DAC_ALIGN_12B_R
118 
119        *** DAC data value to voltage correspondence ***
120        ================================================
121        [..]
122        The analog output voltage on each DAC channel pin is determined
123        by the following equation:
124        [..]
125        DAC_OUTx = VREF+ * DOR / 4095
126        (+) with  DOR is the Data Output Register
127        [..]
128           VREF+ is the input voltage reference (refer to the device datasheet)
129        [..]
130         e.g. To set DAC_OUT1 to 0.7V, use
131        (+) Assuming that VREF+ = 3.3V, DAC_OUT1 = (3.3 * 868) / 4095 = 0.7V
132 
133        *** DMA requests ***
134        =====================
135        [..]
136   #error "Please implement comment here for your STM32 series"
137 
138      [..]
139     (@) For Dual mode and specific signal (Triangle and noise) generation please
140         refer to Extended Features Driver description
141 
142                       ##### How to use this driver #####
143   ==============================================================================
144     [..]
145       (+) DAC APB clock must be enabled to get write access to DAC
146           registers using HAL_DAC_Init()
147   #error "Please implement comment here for your STM32 series"
148       (+) Configure the DAC channel using HAL_DAC_ConfigChannel() function.
149       (+) Enable the DAC channel using HAL_DAC_Start() or HAL_DAC_Start_DMA() functions.
150 
151      *** Calibration mode IO operation ***
152      ======================================
153      [..]
154        (+) Retrieve the factory trimming (calibration settings) using HAL_DACEx_GetTrimOffset()
155        (+) Run the calibration using HAL_DACEx_SelfCalibrate()
156        (+) Update the trimming while DAC running using HAL_DACEx_SetUserTrimming()
157 
158      *** Polling mode IO operation ***
159      =================================
160      [..]
161        (+) Start the DAC peripheral using HAL_DAC_Start()
162        (+) To read the DAC last data output value, use the HAL_DAC_GetValue() function.
163        (+) Stop the DAC peripheral using HAL_DAC_Stop()
164 
165      *** DMA mode IO operation ***
166      ==============================
167      [..]
168        (+) Start the DAC peripheral using HAL_DAC_Start_DMA(), at this stage the user specify the length
169            of data to be transferred at each end of conversion
170            First issued trigger will start the conversion of the value previously set by HAL_DAC_SetValue().
171        (+) At the middle of data transfer HAL_DAC_ConvHalfCpltCallbackCh1()
172            function is executed and user can add his own code by customization of function pointer
173            HAL_DAC_ConvHalfCpltCallbackCh1()
174        (+) At The end of data transfer HAL_DAC_ConvCpltCallbackCh1()
175            function is executed and user can add his own code by customization of function pointer
176            HAL_DAC_ConvCpltCallbackCh1()
177        (+) In case of transfer Error, HAL_DAC_ErrorCallbackCh1() function is executed and user can
178             add his own code by customization of function pointer HAL_DAC_ErrorCallbackCh1
179   #error "Please implement comment here for your STM32 series"
180        (+) Stop the DAC peripheral using HAL_DAC_Stop_DMA()
181 
182     *** Callback registration ***
183     =============================================
184     [..]
185       The compilation define  USE_HAL_DAC_REGISTER_CALLBACKS when set to 1
186       allows the user to configure dynamically the driver callbacks.
187 
188     Use Functions HAL_DAC_RegisterCallback() to register a user callback,
189       it allows to register following callbacks:
190       (+) ConvCpltCallbackCh1     : callback when a half transfer is completed on Ch1.
191       (+) ConvHalfCpltCallbackCh1 : callback when a transfer is completed on Ch1.
192       (+) ErrorCallbackCh1        : callback when an error occurs on Ch1.
193       (+) DMAUnderrunCallbackCh1  : callback when an underrun error occurs on Ch1.
194       (+) MspInitCallback         : DAC MspInit.
195       (+) MspDeInitCallback       : DAC MspdeInit.
196       This function takes as parameters the HAL peripheral handle, the Callback ID
197       and a pointer to the user callback function.
198 
199     Use function HAL_DAC_UnRegisterCallback() to reset a callback to the default
200       weak (overridden) function. It allows to reset following callbacks:
201       (+) ConvCpltCallbackCh1     : callback when a half transfer is completed on Ch1.
202       (+) ConvHalfCpltCallbackCh1 : callback when a transfer is completed on Ch1.
203       (+) ErrorCallbackCh1        : callback when an error occurs on Ch1.
204       (+) DMAUnderrunCallbackCh1  : callback when an underrun error occurs on Ch1.
205       (+) MspInitCallback         : DAC MspInit.
206       (+) MspDeInitCallback       : DAC MspdeInit.
207       (+) All Callbacks
208       This function) takes as parameters the HAL peripheral handle and the Callback ID.
209 
210       By default, after the HAL_DAC_Init and if the state is HAL_DAC_STATE_RESET
211       all callbacks are reset to the corresponding legacy weak (overridden) functions.
212       Exception done for MspInit and MspDeInit callbacks that are respectively
213       reset to the legacy weak (overridden) functions in the HAL_DAC_Init
214       and  HAL_DAC_DeInit only when these callbacks are null (not registered beforehand).
215       If not, MspInit or MspDeInit are not null, the HAL_DAC_Init and HAL_DAC_DeInit
216       keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
217 
218       Callbacks can be registered/unregistered in READY state only.
219       Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
220       in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
221       during the Init/DeInit.
222       In that case first register the MspInit/MspDeInit user callbacks
223       using HAL_DAC_RegisterCallback before calling HAL_DAC_DeInit
224       or HAL_DAC_Init function.
225 
226       When The compilation define USE_HAL_DAC_REGISTER_CALLBACKS is set to 0 or
227       not defined, the callback registering feature is not available
228       and weak (overridden) callbacks are used.
229 
230      *** DAC HAL driver macros list ***
231      =============================================
232      [..]
233        Below the list of most used macros in DAC HAL driver.
234 
235       (+) __HAL_DAC_ENABLE : Enable the DAC peripheral
236       (+) __HAL_DAC_DISABLE : Disable the DAC peripheral
237       (+) __HAL_DAC_CLEAR_FLAG: Clear the DAC's pending flags
238       (+) __HAL_DAC_GET_FLAG: Get the selected DAC's flag status
239 
240      [..]
241       (@) You can refer to the DAC HAL driver header file for more useful macros
242 
243 @endverbatim
244   ******************************************************************************
245   */
246 
247 /* Includes ------------------------------------------------------------------*/
248 #include "stm32u0xx_hal.h"
249 
250 /** @addtogroup STM32U0xx_HAL_Driver
251   * @{
252   */
253 
254 #ifdef HAL_DAC_MODULE_ENABLED
255 #if defined(DAC1)
256 
257 /** @defgroup DAC DAC
258   * @brief DAC driver modules
259   * @{
260   */
261 
262 /* Private typedef -----------------------------------------------------------*/
263 /* Private define ------------------------------------------------------------*/
264 /* Private constants ---------------------------------------------------------*/
265 /** @addtogroup DAC_Private_Constants DAC Private Constants
266   * @{
267   */
268 #define TIMEOUT_DAC_CALIBCONFIG        1U         /* 1   ms        */
269 
270 /**
271   * @}
272   */
273 
274 /* Private macro -------------------------------------------------------------*/
275 /* Private variables ---------------------------------------------------------*/
276 /* Private function prototypes -----------------------------------------------*/
277 /* Exported functions -------------------------------------------------------*/
278 
279 /** @defgroup DAC_Exported_Functions DAC Exported Functions
280   * @{
281   */
282 
283 /** @defgroup DAC_Exported_Functions_Group1 Initialization and de-initialization functions
284   *  @brief    Initialization and Configuration functions
285   *
286 @verbatim
287   ==============================================================================
288               ##### Initialization and de-initialization functions #####
289   ==============================================================================
290     [..]  This section provides functions allowing to:
291       (+) Initialize and configure the DAC.
292       (+) De-initialize the DAC.
293 
294 @endverbatim
295   * @{
296   */
297 
298 /**
299   * @brief  Initialize the DAC peripheral according to the specified parameters
300   *         in the DAC_InitStruct and initialize the associated handle.
301   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
302   *         the configuration information for the specified DAC.
303   * @retval HAL status
304   */
HAL_DAC_Init(DAC_HandleTypeDef * hdac)305 HAL_StatusTypeDef HAL_DAC_Init(DAC_HandleTypeDef *hdac)
306 {
307   /* Check the DAC peripheral handle */
308   if (hdac == NULL)
309   {
310     return HAL_ERROR;
311   }
312   /* Check the parameters */
313   assert_param(IS_DAC_ALL_INSTANCE(hdac->Instance));
314 
315   if (hdac->State == HAL_DAC_STATE_RESET)
316   {
317 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
318     /* Init the DAC Callback settings */
319     hdac->ConvCpltCallbackCh1           = HAL_DAC_ConvCpltCallbackCh1;
320     hdac->ConvHalfCpltCallbackCh1       = HAL_DAC_ConvHalfCpltCallbackCh1;
321     hdac->ErrorCallbackCh1              = HAL_DAC_ErrorCallbackCh1;
322     hdac->DMAUnderrunCallbackCh1        = HAL_DAC_DMAUnderrunCallbackCh1;
323     if (hdac->MspInitCallback == NULL)
324     {
325       hdac->MspInitCallback             = HAL_DAC_MspInit;
326     }
327 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
328 
329     /* Allocate lock resource and initialize it */
330     hdac->Lock = HAL_UNLOCKED;
331 
332 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
333     /* Init the low level hardware */
334     hdac->MspInitCallback(hdac);
335 #else
336     /* Init the low level hardware */
337     HAL_DAC_MspInit(hdac);
338 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
339   }
340 
341   /* Initialize the DAC state*/
342   hdac->State = HAL_DAC_STATE_BUSY;
343 
344   /* Set DAC error code to none */
345   hdac->ErrorCode = HAL_DAC_ERROR_NONE;
346 
347   /* Initialize the DAC state*/
348   hdac->State = HAL_DAC_STATE_READY;
349 
350   /* Return function status */
351   return HAL_OK;
352 }
353 
354 /**
355   * @brief  Deinitialize the DAC peripheral registers to their default reset values.
356   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
357   *         the configuration information for the specified DAC.
358   * @retval HAL status
359   */
HAL_DAC_DeInit(DAC_HandleTypeDef * hdac)360 HAL_StatusTypeDef HAL_DAC_DeInit(DAC_HandleTypeDef *hdac)
361 {
362   /* Check the DAC peripheral handle */
363   if (hdac == NULL)
364   {
365     return HAL_ERROR;
366   }
367 
368   /* Check the parameters */
369   assert_param(IS_DAC_ALL_INSTANCE(hdac->Instance));
370 
371   /* Change DAC state */
372   hdac->State = HAL_DAC_STATE_BUSY;
373 
374 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
375   if (hdac->MspDeInitCallback == NULL)
376   {
377     hdac->MspDeInitCallback = HAL_DAC_MspDeInit;
378   }
379   /* DeInit the low level hardware */
380   hdac->MspDeInitCallback(hdac);
381 #else
382   /* DeInit the low level hardware */
383   HAL_DAC_MspDeInit(hdac);
384 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
385 
386   /* Set DAC error code to none */
387   hdac->ErrorCode = HAL_DAC_ERROR_NONE;
388 
389   /* Change DAC state */
390   hdac->State = HAL_DAC_STATE_RESET;
391 
392   /* Release Lock */
393   __HAL_UNLOCK(hdac);
394 
395   /* Return function status */
396   return HAL_OK;
397 }
398 
399 /**
400   * @brief  Initialize the DAC MSP.
401   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
402   *         the configuration information for the specified DAC.
403   * @retval None
404   */
HAL_DAC_MspInit(DAC_HandleTypeDef * hdac)405 __weak void HAL_DAC_MspInit(DAC_HandleTypeDef *hdac)
406 {
407   /* Prevent unused argument(s) compilation warning */
408   UNUSED(hdac);
409 
410   /* NOTE : This function should not be modified, when the callback is needed,
411             the HAL_DAC_MspInit could be implemented in the user file
412    */
413 }
414 
415 /**
416   * @brief  DeInitialize the DAC MSP.
417   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
418   *         the configuration information for the specified DAC.
419   * @retval None
420   */
HAL_DAC_MspDeInit(DAC_HandleTypeDef * hdac)421 __weak void HAL_DAC_MspDeInit(DAC_HandleTypeDef *hdac)
422 {
423   /* Prevent unused argument(s) compilation warning */
424   UNUSED(hdac);
425 
426   /* NOTE : This function should not be modified, when the callback is needed,
427             the HAL_DAC_MspDeInit could be implemented in the user file
428    */
429 }
430 
431 /**
432   * @}
433   */
434 
435 /** @defgroup DAC_Exported_Functions_Group2 IO operation functions
436   *  @brief    IO operation functions
437   *
438 @verbatim
439   ==============================================================================
440              ##### IO operation functions #####
441   ==============================================================================
442     [..]  This section provides functions allowing to:
443       (+) Start conversion.
444       (+) Stop conversion.
445       (+) Start conversion and enable DMA transfer.
446       (+) Stop conversion and disable DMA transfer.
447       (+) Get result of conversion.
448 
449 @endverbatim
450   * @{
451   */
452 
453 /**
454   * @brief  Enables DAC and starts conversion of channel.
455   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
456   *         the configuration information for the specified DAC.
457   * @param  Channel The selected DAC channel.
458   *          This parameter can be one of the following values:
459   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
460   * @retval HAL status
461   */
HAL_DAC_Start(DAC_HandleTypeDef * hdac,uint32_t Channel)462 HAL_StatusTypeDef HAL_DAC_Start(DAC_HandleTypeDef *hdac, uint32_t Channel)
463 {
464   /* Check the DAC peripheral handle */
465   if (hdac == NULL)
466   {
467     return HAL_ERROR;
468   }
469 
470   /* Check the parameters */
471   assert_param(IS_DAC_CHANNEL(Channel));
472 
473   /* Process locked */
474   __HAL_LOCK(hdac);
475 
476   /* Change DAC state */
477   hdac->State = HAL_DAC_STATE_BUSY;
478 
479   /* Enable the Peripheral */
480   __HAL_DAC_ENABLE(hdac, Channel);
481 
482   /* Check if software trigger enabled */
483   if ((hdac->Instance->CR & (DAC_CR_TEN1 | DAC_CR_TSEL1)) == DAC_TRIGGER_SOFTWARE)
484   {
485     /* Enable the selected DAC software conversion */
486     SET_BIT(hdac->Instance->SWTRIGR, DAC_SWTRIGR_SWTRIG1);
487   }
488 
489   /* Change DAC state */
490   hdac->State = HAL_DAC_STATE_READY;
491 
492   /* Process unlocked */
493   __HAL_UNLOCK(hdac);
494 
495   /* Return function status */
496   return HAL_OK;
497 }
498 
499 /**
500   * @brief  Disables DAC and stop conversion of channel.
501   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
502   *         the configuration information for the specified DAC.
503   * @param  Channel The selected DAC channel.
504   *          This parameter can be one of the following values:
505   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
506   * @retval HAL status
507   */
HAL_DAC_Stop(DAC_HandleTypeDef * hdac,uint32_t Channel)508 HAL_StatusTypeDef HAL_DAC_Stop(DAC_HandleTypeDef *hdac, uint32_t Channel)
509 {
510   /* Check the DAC peripheral handle */
511   if (hdac == NULL)
512   {
513     return HAL_ERROR;
514   }
515 
516   /* Check the parameters */
517   assert_param(IS_DAC_CHANNEL(Channel));
518 
519   /* Disable the Peripheral */
520   __HAL_DAC_DISABLE(hdac, Channel);
521 
522   /* Change DAC state */
523   hdac->State = HAL_DAC_STATE_READY;
524 
525   /* Return function status */
526   return HAL_OK;
527 }
528 
529 /**
530   * @brief  Enables DAC and starts conversion of channel.
531   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
532   *         the configuration information for the specified DAC.
533   * @param  Channel The selected DAC channel.
534   *          This parameter can be one of the following values:
535   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
536   * @param  pData The source Buffer address.
537   * @param  Length The length of data to be transferred from memory to DAC peripheral
538   * @param  Alignment Specifies the data alignment for DAC channel.
539   *          This parameter can be one of the following values:
540   *            @arg DAC_ALIGN_8B_R: 8bit right data alignment selected
541   *            @arg DAC_ALIGN_12B_L: 12bit left data alignment selected
542   *            @arg DAC_ALIGN_12B_R: 12bit right data alignment selected
543   * @retval HAL status
544   */
HAL_DAC_Start_DMA(DAC_HandleTypeDef * hdac,uint32_t Channel,const uint32_t * pData,uint32_t Length,uint32_t Alignment)545 HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel, const uint32_t *pData, uint32_t Length,
546                                     uint32_t Alignment)
547 {
548   HAL_StatusTypeDef status;
549   uint32_t tmpreg = 0U;
550 
551   /* Check the DAC peripheral handle */
552   if (hdac == NULL)
553   {
554     return HAL_ERROR;
555   }
556 
557   /* Check the parameters */
558   assert_param(IS_DAC_CHANNEL(Channel));
559   assert_param(IS_DAC_ALIGN(Alignment));
560 
561   /* Process locked */
562   __HAL_LOCK(hdac);
563 
564   /* Change DAC state */
565   hdac->State = HAL_DAC_STATE_BUSY;
566 
567   if (Channel == DAC_CHANNEL_1)
568   {
569     /* Set the DMA transfer complete callback for channel1 */
570     hdac->DMA_Handle1->XferCpltCallback = DAC_DMAConvCpltCh1;
571 
572     /* Set the DMA half transfer complete callback for channel1 */
573     hdac->DMA_Handle1->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh1;
574 
575     /* Set the DMA error callback for channel1 */
576     hdac->DMA_Handle1->XferErrorCallback = DAC_DMAErrorCh1;
577 
578     /* Enable the selected DAC channel1 DMA request */
579     SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN1);
580 
581     /* Case of use of channel 1 */
582     switch (Alignment)
583     {
584       case DAC_ALIGN_12B_R:
585         /* Get DHR12R1 address */
586         tmpreg = (uint32_t)&hdac->Instance->DHR12R1;
587         break;
588       case DAC_ALIGN_12B_L:
589         /* Get DHR12L1 address */
590         tmpreg = (uint32_t)&hdac->Instance->DHR12L1;
591         break;
592       default: /* case DAC_ALIGN_8B_R */
593         /* Get DHR8R1 address */
594         tmpreg = (uint32_t)&hdac->Instance->DHR8R1;
595         break;
596     }
597   }
598 
599   /* Enable the DAC DMA underrun interrupt */
600   __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR1);
601 
602   /* Enable the DMA channel */
603   status = HAL_DMA_Start_IT(hdac->DMA_Handle1, (uint32_t)pData, tmpreg, Length);
604 
605   /* Process Unlocked */
606   __HAL_UNLOCK(hdac);
607 
608   if (status == HAL_OK)
609   {
610     /* Enable the Peripheral */
611     __HAL_DAC_ENABLE(hdac, Channel);
612   }
613   else
614   {
615     hdac->ErrorCode |= HAL_DAC_ERROR_DMA;
616   }
617 
618   /* Return function status */
619   return status;
620 }
621 
622 /**
623   * @brief  Disables DAC and stop conversion of channel.
624   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
625   *         the configuration information for the specified DAC.
626   * @param  Channel The selected DAC channel.
627   *          This parameter can be one of the following values:
628   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
629   * @retval HAL status
630   */
HAL_DAC_Stop_DMA(DAC_HandleTypeDef * hdac,uint32_t Channel)631 HAL_StatusTypeDef HAL_DAC_Stop_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel)
632 {
633   /* Check the DAC peripheral handle */
634   if (hdac == NULL)
635   {
636     return HAL_ERROR;
637   }
638 
639   /* Check the parameters */
640   assert_param(IS_DAC_CHANNEL(Channel));
641 
642   /* Disable the selected DAC channel DMA request */
643   hdac->Instance->CR &= ~(DAC_CR_DMAEN1 << (Channel & 0x10UL));
644 
645   /* Disable the Peripheral */
646   __HAL_DAC_DISABLE(hdac, Channel);
647 
648   /* Disable the DMA channel */
649 
650   /* Disable the DMA channel */
651   (void)HAL_DMA_Abort(hdac->DMA_Handle1);
652 
653   /* Disable the DAC DMA underrun interrupt */
654   __HAL_DAC_DISABLE_IT(hdac, DAC_IT_DMAUDR1);
655 
656   /* Change DAC state */
657   hdac->State = HAL_DAC_STATE_READY;
658 
659   /* Return function status */
660   return HAL_OK;
661 }
662 
663 /**
664   * @brief  Handles DAC interrupt request
665   *         This function uses the interruption of DMA
666   *         underrun.
667   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
668   *         the configuration information for the specified DAC.
669   * @retval None
670   */
HAL_DAC_IRQHandler(DAC_HandleTypeDef * hdac)671 void HAL_DAC_IRQHandler(DAC_HandleTypeDef *hdac)
672 {
673   uint32_t itsource = hdac->Instance->CR;
674   uint32_t itflag   = hdac->Instance->SR;
675 
676   if ((itsource & DAC_IT_DMAUDR1) == DAC_IT_DMAUDR1)
677   {
678     /* Check underrun flag of DAC channel 1 */
679     if ((itflag & DAC_FLAG_DMAUDR1) == DAC_FLAG_DMAUDR1)
680     {
681       /* Change DAC state to error state */
682       hdac->State = HAL_DAC_STATE_ERROR;
683 
684       /* Set DAC error code to channel1 DMA underrun error */
685       SET_BIT(hdac->ErrorCode, HAL_DAC_ERROR_DMAUNDERRUNCH1);
686 
687       /* Clear the underrun flag */
688       __HAL_DAC_CLEAR_FLAG(hdac, DAC_FLAG_DMAUDR1);
689 
690       /* Disable the selected DAC channel1 DMA request */
691       __HAL_DAC_DISABLE_IT(hdac, DAC_CR_DMAEN1);
692 
693       /* Error callback */
694 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
695       hdac->DMAUnderrunCallbackCh1(hdac);
696 #else
697       HAL_DAC_DMAUnderrunCallbackCh1(hdac);
698 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
699     }
700   }
701 }
702 
703 /**
704   * @brief  Set the specified data holding register value for DAC channel.
705   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
706   *         the configuration information for the specified DAC.
707   * @param  Channel The selected DAC channel.
708   *          This parameter can be one of the following values:
709   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
710   * @param  Alignment Specifies the data alignment.
711   *          This parameter can be one of the following values:
712   *            @arg DAC_ALIGN_8B_R: 8bit right data alignment selected
713   *            @arg DAC_ALIGN_12B_L: 12bit left data alignment selected
714   *            @arg DAC_ALIGN_12B_R: 12bit right data alignment selected
715   * @param  Data Data to be loaded in the selected data holding register.
716   * @retval HAL status
717   */
HAL_DAC_SetValue(DAC_HandleTypeDef * hdac,uint32_t Channel,uint32_t Alignment,uint32_t Data)718 HAL_StatusTypeDef HAL_DAC_SetValue(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data)
719 {
720   __IO uint32_t tmp = 0UL;
721 
722   /* Check the DAC peripheral handle */
723   if (hdac == NULL)
724   {
725     return HAL_ERROR;
726   }
727 
728   /* Check the parameters */
729   assert_param(IS_DAC_CHANNEL(Channel));
730   assert_param(IS_DAC_ALIGN(Alignment));
731   assert_param(IS_DAC_DATA(Data));
732 
733   tmp = (uint32_t)hdac->Instance;
734   if (Channel == DAC_CHANNEL_1)
735   {
736     tmp += DAC_DHR12R1_ALIGNMENT(Alignment);
737   }
738 
739   /* Set the DAC channel selected data holding register */
740   *(__IO uint32_t *) tmp = Data;
741 
742   /* Return function status */
743   return HAL_OK;
744 }
745 
746 /**
747   * @brief  Conversion complete callback in non-blocking mode for Channel1
748   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
749   *         the configuration information for the specified DAC.
750   * @retval None
751   */
HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef * hdac)752 __weak void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef *hdac)
753 {
754   /* Prevent unused argument(s) compilation warning */
755   UNUSED(hdac);
756 
757   /* NOTE : This function should not be modified, when the callback is needed,
758             the HAL_DAC_ConvCpltCallbackCh1 could be implemented in the user file
759    */
760 }
761 
762 /**
763   * @brief  Conversion half DMA transfer callback in non-blocking mode for Channel1
764   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
765   *         the configuration information for the specified DAC.
766   * @retval None
767   */
HAL_DAC_ConvHalfCpltCallbackCh1(DAC_HandleTypeDef * hdac)768 __weak void HAL_DAC_ConvHalfCpltCallbackCh1(DAC_HandleTypeDef *hdac)
769 {
770   /* Prevent unused argument(s) compilation warning */
771   UNUSED(hdac);
772 
773   /* NOTE : This function should not be modified, when the callback is needed,
774             the HAL_DAC_ConvHalfCpltCallbackCh1 could be implemented in the user file
775    */
776 }
777 
778 /**
779   * @brief  Error DAC callback for Channel1.
780   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
781   *         the configuration information for the specified DAC.
782   * @retval None
783   */
HAL_DAC_ErrorCallbackCh1(DAC_HandleTypeDef * hdac)784 __weak void HAL_DAC_ErrorCallbackCh1(DAC_HandleTypeDef *hdac)
785 {
786   /* Prevent unused argument(s) compilation warning */
787   UNUSED(hdac);
788 
789   /* NOTE : This function should not be modified, when the callback is needed,
790             the HAL_DAC_ErrorCallbackCh1 could be implemented in the user file
791    */
792 }
793 
794 /**
795   * @brief  DMA underrun DAC callback for channel1.
796   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
797   *         the configuration information for the specified DAC.
798   * @retval None
799   */
HAL_DAC_DMAUnderrunCallbackCh1(DAC_HandleTypeDef * hdac)800 __weak void HAL_DAC_DMAUnderrunCallbackCh1(DAC_HandleTypeDef *hdac)
801 {
802   /* Prevent unused argument(s) compilation warning */
803   UNUSED(hdac);
804 
805   /* NOTE : This function should not be modified, when the callback is needed,
806             the HAL_DAC_DMAUnderrunCallbackCh1 could be implemented in the user file
807    */
808 }
809 
810 /**
811   * @}
812   */
813 
814 /** @defgroup DAC_Exported_Functions_Group3 Peripheral Control functions
815   *  @brief    Peripheral Control functions
816   *
817 @verbatim
818   ==============================================================================
819              ##### Peripheral Control functions #####
820   ==============================================================================
821     [..]  This section provides functions allowing to:
822       (+) Configure channels.
823       (+) Set the specified data holding register value for DAC channel.
824 
825 @endverbatim
826   * @{
827   */
828 
829 /**
830   * @brief  Returns the last data output value of the selected DAC channel.
831   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
832   *         the configuration information for the specified DAC.
833   * @param  Channel The selected DAC channel.
834   *          This parameter can be one of the following values:
835   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
836   * @retval The selected DAC channel data output value.
837   */
HAL_DAC_GetValue(const DAC_HandleTypeDef * hdac,uint32_t Channel)838 uint32_t HAL_DAC_GetValue(const DAC_HandleTypeDef *hdac, uint32_t Channel)
839 {
840   uint32_t result;
841 
842   /* Check the DAC peripheral handle */
843   if (hdac == NULL)
844   {
845     return HAL_ERROR;
846   }
847 
848   /* Check the parameters */
849   assert_param(IS_DAC_CHANNEL(Channel));
850 
851   result = hdac->Instance->DOR1;
852 
853   /* Returns the DAC channel data output register value */
854   return result;
855 }
856 
857 /**
858   * @brief  Configures the selected DAC channel.
859   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
860   *         the configuration information for the specified DAC.
861   * @param  sConfig DAC configuration structure.
862   * @param  Channel The selected DAC channel.
863   *          This parameter can be one of the following values:
864   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
865   * @retval HAL status
866   */
HAL_DAC_ConfigChannel(DAC_HandleTypeDef * hdac,const DAC_ChannelConfTypeDef * sConfig,uint32_t Channel)867 HAL_StatusTypeDef HAL_DAC_ConfigChannel(DAC_HandleTypeDef *hdac,
868                                         const DAC_ChannelConfTypeDef *sConfig, uint32_t Channel)
869 {
870   HAL_StatusTypeDef status = HAL_OK;
871   uint32_t tmpreg1;
872   uint32_t tmpreg2;
873   uint32_t tickstart;
874   uint32_t connectOnChip;
875 
876   /* Check the DAC peripheral handle and channel configuration struct */
877   if ((hdac == NULL) || (sConfig == NULL))
878   {
879     return HAL_ERROR;
880   }
881 
882   /* Check the DAC parameters */
883   assert_param(IS_DAC_TRIGGER(sConfig->DAC_Trigger));
884   assert_param(IS_DAC_OUTPUT_BUFFER_STATE(sConfig->DAC_OutputBuffer));
885   assert_param(IS_DAC_CHIP_CONNECTION(sConfig->DAC_ConnectOnChipPeripheral));
886   assert_param(IS_DAC_TRIMMING(sConfig->DAC_UserTrimming));
887   if ((sConfig->DAC_UserTrimming) == DAC_TRIMMING_USER)
888   {
889     assert_param(IS_DAC_TRIMMINGVALUE(sConfig->DAC_TrimmingValue));
890   }
891   assert_param(IS_DAC_SAMPLEANDHOLD(sConfig->DAC_SampleAndHold));
892   if ((sConfig->DAC_SampleAndHold) == DAC_SAMPLEANDHOLD_ENABLE)
893   {
894     assert_param(IS_DAC_SAMPLETIME(sConfig->DAC_SampleAndHoldConfig.DAC_SampleTime));
895     assert_param(IS_DAC_HOLDTIME(sConfig->DAC_SampleAndHoldConfig.DAC_HoldTime));
896     assert_param(IS_DAC_REFRESHTIME(sConfig->DAC_SampleAndHoldConfig.DAC_RefreshTime));
897   }
898   assert_param(IS_DAC_CHANNEL(Channel));
899 
900   /* Process locked */
901   __HAL_LOCK(hdac);
902 
903   /* Change DAC state */
904   hdac->State = HAL_DAC_STATE_BUSY;
905 
906   /* Sample and hold configuration */
907   if (sConfig->DAC_SampleAndHold == DAC_SAMPLEANDHOLD_ENABLE)
908   {
909     /* Get timeout */
910     tickstart = HAL_GetTick();
911 
912     /* SHSR1 can be written when BWST1 is cleared */
913     while (((hdac->Instance->SR) & DAC_SR_BWST1) != 0UL)
914     {
915       /* Check for the Timeout */
916       if ((HAL_GetTick() - tickstart) > TIMEOUT_DAC_CALIBCONFIG)
917       {
918         /* New check to avoid false timeout detection in case of preemption */
919         if (((hdac->Instance->SR) & DAC_SR_BWST1) != 0UL)
920         {
921           /* Update error code */
922           SET_BIT(hdac->ErrorCode, HAL_DAC_ERROR_TIMEOUT);
923 
924           /* Change the DMA state */
925           hdac->State = HAL_DAC_STATE_TIMEOUT;
926 
927           return HAL_TIMEOUT;
928         }
929       }
930     }
931     hdac->Instance->SHSR1 = sConfig->DAC_SampleAndHoldConfig.DAC_SampleTime;
932 
933     /* HoldTime */
934     MODIFY_REG(hdac->Instance->SHHR, DAC_SHHR_THOLD1 << (Channel & 0x10UL),
935                (sConfig->DAC_SampleAndHoldConfig.DAC_HoldTime) << (Channel & 0x10UL));
936     /* RefreshTime */
937     MODIFY_REG(hdac->Instance->SHRR, DAC_SHRR_TREFRESH1 << (Channel & 0x10UL),
938                (sConfig->DAC_SampleAndHoldConfig.DAC_RefreshTime) << (Channel & 0x10UL));
939   }
940 
941   if (sConfig->DAC_UserTrimming == DAC_TRIMMING_USER)
942     /* USER TRIMMING */
943   {
944     /* Get the DAC CCR value */
945     tmpreg1 = hdac->Instance->CCR;
946     /* Clear trimming value */
947     tmpreg1 &= ~(((uint32_t)(DAC_CCR_OTRIM1)) << (Channel & 0x10UL));
948     /* Configure for the selected trimming offset */
949     tmpreg2 = sConfig->DAC_TrimmingValue;
950     /* Calculate CCR register value depending on DAC_Channel */
951     tmpreg1 |= tmpreg2 << (Channel & 0x10UL);
952     /* Write to DAC CCR */
953     hdac->Instance->CCR = tmpreg1;
954   }
955   /* else factory trimming is used (factory setting are available at reset)*/
956   /* SW Nothing has nothing to do */
957 
958   /* Get the DAC MCR value */
959   tmpreg1 = hdac->Instance->MCR;
960   /* Clear DAC_MCR_MODEx bits */
961   tmpreg1 &= ~(((uint32_t)(DAC_MCR_MODE1)) << (Channel & 0x10UL));
962   /* Configure for the selected DAC channel: mode, buffer output & on chip peripheral connect */
963 
964 
965   if (sConfig->DAC_ConnectOnChipPeripheral == DAC_CHIPCONNECT_EXTERNAL)
966   {
967     connectOnChip = 0x00000000UL;
968   }
969   else if (sConfig->DAC_ConnectOnChipPeripheral == DAC_CHIPCONNECT_INTERNAL)
970   {
971     connectOnChip = DAC_MCR_MODE1_0;
972   }
973   else /* (sConfig->DAC_ConnectOnChipPeripheral == DAC_CHIPCONNECT_BOTH) */
974   {
975     if (sConfig->DAC_OutputBuffer == DAC_OUTPUTBUFFER_ENABLE)
976     {
977       connectOnChip = DAC_MCR_MODE1_0;
978     }
979     else
980     {
981       connectOnChip = 0x00000000UL;
982     }
983   }
984   tmpreg2 = (sConfig->DAC_SampleAndHold | sConfig->DAC_OutputBuffer | connectOnChip);
985   /* Calculate MCR register value depending on DAC_Channel */
986   tmpreg1 |= tmpreg2 << (Channel & 0x10UL);
987   /* Write to DAC MCR */
988   hdac->Instance->MCR = tmpreg1;
989 
990   /* DAC in normal operating mode hence clear DAC_CR_CENx bit */
991   CLEAR_BIT(hdac->Instance->CR, DAC_CR_CEN1 << (Channel & 0x10UL));
992 
993   /* Get the DAC CR value */
994   tmpreg1 = hdac->Instance->CR;
995   /* Clear TENx, TSELx, WAVEx and MAMPx bits */
996   tmpreg1 &= ~(((uint32_t)(DAC_CR_MAMP1 | DAC_CR_WAVE1 | DAC_CR_TSEL1 | DAC_CR_TEN1)) << (Channel & 0x10UL));
997   /* Configure for the selected DAC channel: trigger */
998   /* Set TSELx and TENx bits according to DAC_Trigger value */
999   tmpreg2 = sConfig->DAC_Trigger;
1000   /* Calculate CR register value depending on DAC_Channel */
1001   tmpreg1 |= tmpreg2 << (Channel & 0x10UL);
1002   /* Write to DAC CR */
1003   hdac->Instance->CR = tmpreg1;
1004   /* Disable wave generation */
1005   CLEAR_BIT(hdac->Instance->CR, (DAC_CR_WAVE1 << (Channel & 0x10UL)));
1006 
1007   /* Change DAC state */
1008   hdac->State = HAL_DAC_STATE_READY;
1009 
1010   /* Process unlocked */
1011   __HAL_UNLOCK(hdac);
1012 
1013   /* Return function status */
1014   return status;
1015 }
1016 
1017 /**
1018   * @}
1019   */
1020 
1021 /** @defgroup DAC_Exported_Functions_Group4 Peripheral State and Errors functions
1022   *  @brief   Peripheral State and Errors functions
1023   *
1024 @verbatim
1025   ==============================================================================
1026             ##### Peripheral State and Errors functions #####
1027   ==============================================================================
1028     [..]
1029     This subsection provides functions allowing to
1030       (+) Check the DAC state.
1031       (+) Check the DAC Errors.
1032 
1033 @endverbatim
1034   * @{
1035   */
1036 
1037 /**
1038   * @brief  return the DAC handle state
1039   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
1040   *         the configuration information for the specified DAC.
1041   * @retval HAL state
1042   */
HAL_DAC_GetState(const DAC_HandleTypeDef * hdac)1043 HAL_DAC_StateTypeDef HAL_DAC_GetState(const DAC_HandleTypeDef *hdac)
1044 {
1045   /* Return DAC handle state */
1046   return hdac->State;
1047 }
1048 
1049 
1050 /**
1051   * @brief  Return the DAC error code
1052   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
1053   *         the configuration information for the specified DAC.
1054   * @retval DAC Error Code
1055   */
HAL_DAC_GetError(const DAC_HandleTypeDef * hdac)1056 uint32_t HAL_DAC_GetError(const DAC_HandleTypeDef *hdac)
1057 {
1058   return hdac->ErrorCode;
1059 }
1060 
1061 /**
1062   * @}
1063   */
1064 
1065 /**
1066   * @}
1067   */
1068 
1069 /** @addtogroup DAC_Exported_Functions
1070   * @{
1071   */
1072 
1073 /** @addtogroup DAC_Exported_Functions_Group1
1074   * @{
1075   */
1076 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
1077 /**
1078   * @brief  Register a User DAC Callback
1079   *         To be used instead of the weak (overridden) predefined callback
1080   * @note   The HAL_DAC_RegisterCallback() may be called before HAL_DAC_Init() in HAL_DAC_STATE_RESET to register
1081   *         callbacks for HAL_DAC_MSPINIT_CB_ID and HAL_DAC_MSPDEINIT_CB_ID
1082   * @param  hdac DAC handle
1083   * @param  CallbackID ID of the callback to be registered
1084   *         This parameter can be one of the following values:
1085   *          @arg @ref HAL_DAC_ERROR_INVALID_CALLBACK   DAC Error Callback ID
1086   *          @arg @ref HAL_DAC_CH1_COMPLETE_CB_ID       DAC CH1 Complete Callback ID
1087   *          @arg @ref HAL_DAC_CH1_HALF_COMPLETE_CB_ID  DAC CH1 Half Complete Callback ID
1088   *          @arg @ref HAL_DAC_CH1_ERROR_ID             DAC CH1 Error Callback ID
1089   *          @arg @ref HAL_DAC_CH1_UNDERRUN_CB_ID       DAC CH1 UnderRun Callback ID
1090   *          @arg @ref HAL_DAC_MSPINIT_CB_ID            DAC MSP Init Callback ID
1091   *          @arg @ref HAL_DAC_MSPDEINIT_CB_ID          DAC MSP DeInit Callback ID
1092   *
1093   * @param  pCallback pointer to the Callback function
1094   * @retval status
1095   */
HAL_DAC_RegisterCallback(DAC_HandleTypeDef * hdac,HAL_DAC_CallbackIDTypeDef CallbackID,pDAC_CallbackTypeDef pCallback)1096 HAL_StatusTypeDef HAL_DAC_RegisterCallback(DAC_HandleTypeDef *hdac, HAL_DAC_CallbackIDTypeDef CallbackID,
1097                                            pDAC_CallbackTypeDef pCallback)
1098 {
1099   HAL_StatusTypeDef status = HAL_OK;
1100 
1101   /* Check the DAC peripheral handle */
1102   if (hdac == NULL)
1103   {
1104     return HAL_ERROR;
1105   }
1106 
1107   if (pCallback == NULL)
1108   {
1109     /* Update the error code */
1110     hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK;
1111     return HAL_ERROR;
1112   }
1113 
1114   if (hdac->State == HAL_DAC_STATE_READY)
1115   {
1116     switch (CallbackID)
1117     {
1118       case HAL_DAC_CH1_COMPLETE_CB_ID :
1119         hdac->ConvCpltCallbackCh1 = pCallback;
1120         break;
1121       case HAL_DAC_CH1_HALF_COMPLETE_CB_ID :
1122         hdac->ConvHalfCpltCallbackCh1 = pCallback;
1123         break;
1124       case HAL_DAC_CH1_ERROR_ID :
1125         hdac->ErrorCallbackCh1 = pCallback;
1126         break;
1127       case HAL_DAC_CH1_UNDERRUN_CB_ID :
1128         hdac->DMAUnderrunCallbackCh1 = pCallback;
1129         break;
1130       case HAL_DAC_MSPINIT_CB_ID :
1131         hdac->MspInitCallback = pCallback;
1132         break;
1133       case HAL_DAC_MSPDEINIT_CB_ID :
1134         hdac->MspDeInitCallback = pCallback;
1135         break;
1136       default :
1137         /* Update the error code */
1138         hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK;
1139         /* update return status */
1140         status =  HAL_ERROR;
1141         break;
1142     }
1143   }
1144   else if (hdac->State == HAL_DAC_STATE_RESET)
1145   {
1146     switch (CallbackID)
1147     {
1148       case HAL_DAC_MSPINIT_CB_ID :
1149         hdac->MspInitCallback = pCallback;
1150         break;
1151       case HAL_DAC_MSPDEINIT_CB_ID :
1152         hdac->MspDeInitCallback = pCallback;
1153         break;
1154       default :
1155         /* Update the error code */
1156         hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK;
1157         /* update return status */
1158         status =  HAL_ERROR;
1159         break;
1160     }
1161   }
1162   else
1163   {
1164     /* Update the error code */
1165     hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK;
1166     /* update return status */
1167     status =  HAL_ERROR;
1168   }
1169 
1170   return status;
1171 }
1172 
1173 /**
1174   * @brief  Unregister a User DAC Callback
1175   *         DAC Callback is redirected to the weak (overridden) predefined callback
1176   * @note   The HAL_DAC_UnRegisterCallback() may be called before HAL_DAC_Init() in HAL_DAC_STATE_RESET to un-register
1177   *         callbacks for HAL_DAC_MSPINIT_CB_ID and HAL_DAC_MSPDEINIT_CB_ID
1178   * @param  hdac DAC handle
1179   * @param  CallbackID ID of the callback to be unregistered
1180   *         This parameter can be one of the following values:
1181   *          @arg @ref HAL_DAC_CH1_COMPLETE_CB_ID          DAC CH1 transfer Complete Callback ID
1182   *          @arg @ref HAL_DAC_CH1_HALF_COMPLETE_CB_ID     DAC CH1 Half Complete Callback ID
1183   *          @arg @ref HAL_DAC_CH1_ERROR_ID                DAC CH1 Error Callback ID
1184   *          @arg @ref HAL_DAC_CH1_UNDERRUN_CB_ID          DAC CH1 UnderRun Callback ID
1185   *          @arg @ref HAL_DAC_MSPINIT_CB_ID               DAC MSP Init Callback ID
1186   *          @arg @ref HAL_DAC_MSPDEINIT_CB_ID             DAC MSP DeInit Callback ID
1187   *          @arg @ref HAL_DAC_ALL_CB_ID                   DAC All callbacks
1188   * @retval status
1189   */
HAL_DAC_UnRegisterCallback(DAC_HandleTypeDef * hdac,HAL_DAC_CallbackIDTypeDef CallbackID)1190 HAL_StatusTypeDef HAL_DAC_UnRegisterCallback(DAC_HandleTypeDef *hdac, HAL_DAC_CallbackIDTypeDef CallbackID)
1191 {
1192   HAL_StatusTypeDef status = HAL_OK;
1193 
1194   /* Check the DAC peripheral handle */
1195   if (hdac == NULL)
1196   {
1197     return HAL_ERROR;
1198   }
1199 
1200   if (hdac->State == HAL_DAC_STATE_READY)
1201   {
1202     switch (CallbackID)
1203     {
1204       case HAL_DAC_CH1_COMPLETE_CB_ID :
1205         hdac->ConvCpltCallbackCh1 = HAL_DAC_ConvCpltCallbackCh1;
1206         break;
1207       case HAL_DAC_CH1_HALF_COMPLETE_CB_ID :
1208         hdac->ConvHalfCpltCallbackCh1 = HAL_DAC_ConvHalfCpltCallbackCh1;
1209         break;
1210       case HAL_DAC_CH1_ERROR_ID :
1211         hdac->ErrorCallbackCh1 = HAL_DAC_ErrorCallbackCh1;
1212         break;
1213       case HAL_DAC_CH1_UNDERRUN_CB_ID :
1214         hdac->DMAUnderrunCallbackCh1 = HAL_DAC_DMAUnderrunCallbackCh1;
1215         break;
1216       case HAL_DAC_MSPINIT_CB_ID :
1217         hdac->MspInitCallback = HAL_DAC_MspInit;
1218         break;
1219       case HAL_DAC_MSPDEINIT_CB_ID :
1220         hdac->MspDeInitCallback = HAL_DAC_MspDeInit;
1221         break;
1222       case HAL_DAC_ALL_CB_ID :
1223         hdac->ConvCpltCallbackCh1 = HAL_DAC_ConvCpltCallbackCh1;
1224         hdac->ConvHalfCpltCallbackCh1 = HAL_DAC_ConvHalfCpltCallbackCh1;
1225         hdac->ErrorCallbackCh1 = HAL_DAC_ErrorCallbackCh1;
1226         hdac->DMAUnderrunCallbackCh1 = HAL_DAC_DMAUnderrunCallbackCh1;
1227         hdac->MspInitCallback = HAL_DAC_MspInit;
1228         hdac->MspDeInitCallback = HAL_DAC_MspDeInit;
1229         break;
1230       default :
1231         /* Update the error code */
1232         hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK;
1233         /* update return status */
1234         status =  HAL_ERROR;
1235         break;
1236     }
1237   }
1238   else if (hdac->State == HAL_DAC_STATE_RESET)
1239   {
1240     switch (CallbackID)
1241     {
1242       case HAL_DAC_MSPINIT_CB_ID :
1243         hdac->MspInitCallback = HAL_DAC_MspInit;
1244         break;
1245       case HAL_DAC_MSPDEINIT_CB_ID :
1246         hdac->MspDeInitCallback = HAL_DAC_MspDeInit;
1247         break;
1248       default :
1249         /* Update the error code */
1250         hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK;
1251         /* update return status */
1252         status =  HAL_ERROR;
1253         break;
1254     }
1255   }
1256   else
1257   {
1258     /* Update the error code */
1259     hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK;
1260     /* update return status */
1261     status =  HAL_ERROR;
1262   }
1263 
1264   return status;
1265 }
1266 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
1267 
1268 /**
1269   * @}
1270   */
1271 
1272 /**
1273   * @}
1274   */
1275 
1276 /** @addtogroup DAC_Private_Functions
1277   * @{
1278   */
1279 
1280 /**
1281   * @brief  DMA conversion complete callback.
1282   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1283   *                the configuration information for the specified DMA module.
1284   * @retval None
1285   */
DAC_DMAConvCpltCh1(DMA_HandleTypeDef * hdma)1286 void DAC_DMAConvCpltCh1(DMA_HandleTypeDef *hdma)
1287 {
1288   DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1289 
1290 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
1291   hdac->ConvCpltCallbackCh1(hdac);
1292 #else
1293   HAL_DAC_ConvCpltCallbackCh1(hdac);
1294 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
1295 
1296   hdac->State = HAL_DAC_STATE_READY;
1297 }
1298 
1299 /**
1300   * @brief  DMA half transfer complete callback.
1301   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1302   *                the configuration information for the specified DMA module.
1303   * @retval None
1304   */
DAC_DMAHalfConvCpltCh1(DMA_HandleTypeDef * hdma)1305 void DAC_DMAHalfConvCpltCh1(DMA_HandleTypeDef *hdma)
1306 {
1307   DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1308   /* Conversion complete callback */
1309 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
1310   hdac->ConvHalfCpltCallbackCh1(hdac);
1311 #else
1312   HAL_DAC_ConvHalfCpltCallbackCh1(hdac);
1313 #endif  /* USE_HAL_DAC_REGISTER_CALLBACKS */
1314 }
1315 
1316 /**
1317   * @brief  DMA error callback
1318   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1319   *                the configuration information for the specified DMA module.
1320   * @retval None
1321   */
DAC_DMAErrorCh1(DMA_HandleTypeDef * hdma)1322 void DAC_DMAErrorCh1(DMA_HandleTypeDef *hdma)
1323 {
1324   DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1325 
1326   /* Set DAC error code to DMA error */
1327   hdac->ErrorCode |= HAL_DAC_ERROR_DMA;
1328 
1329 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
1330   hdac->ErrorCallbackCh1(hdac);
1331 #else
1332   HAL_DAC_ErrorCallbackCh1(hdac);
1333 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
1334 
1335   hdac->State = HAL_DAC_STATE_READY;
1336 }
1337 
1338 /**
1339   * @}
1340   */
1341 
1342 /**
1343   * @}
1344   */
1345 
1346 #endif /* DAC1 */
1347 
1348 #endif /* HAL_DAC_MODULE_ENABLED */
1349 /**
1350   * @}
1351   */
1352