Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:06

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_dac.c
0004   * @author  MCD Application Team
0005   * @brief   DAC HAL module driver.
0006   *         This file provides firmware functions to manage the following
0007   *         functionalities of the Digital to Analog Converter (DAC) peripheral:
0008   *           + Initialization and de-initialization functions
0009   *           + IO operation functions
0010   *           + Peripheral Control functions
0011   *           + Peripheral State and Errors functions
0012   *
0013   *
0014   ******************************************************************************
0015   * @attention
0016   *
0017   * Copyright (c) 2017 STMicroelectronics.
0018   * All rights reserved.
0019   *
0020   * This software is licensed under terms that can be found in the LICENSE file
0021   * in the root directory of this software component.
0022   * If no LICENSE file comes with this software, it is provided AS-IS.
0023   *
0024   ******************************************************************************
0025   @verbatim
0026   ==============================================================================
0027                       ##### DAC Peripheral features #####
0028   ==============================================================================
0029     [..]
0030       *** DAC Channels ***
0031       ====================
0032     [..]
0033     STM32H7 devices integrate two 12-bit Digital Analog Converters
0034 
0035     The 2 converters (i.e. channel1 & channel2)
0036     can be used independently or simultaneously (dual mode):
0037       (#) DAC channel1 with DAC_OUT1 (PA4) as output or connected to on-chip
0038           peripherals (ex. OPAMPs, comparators).
0039       (#) DAC channel2 with DAC_OUT2 (PA5) as output or connected to on-chip
0040           peripherals (ex. OPAMPs, comparators).
0041 
0042       *** DAC Triggers ***
0043       ====================
0044     [..]
0045     Digital to Analog conversion can be non-triggered using DAC_TRIGGER_NONE
0046     and DAC_OUT1/DAC_OUT2 is available once writing to DHRx register.
0047     [..]
0048     Digital to Analog conversion can be triggered by:
0049       (#) External event: EXTI Line 9 (any GPIOx_PIN_9) using DAC_TRIGGER_EXT_IT9.
0050           The used pin (GPIOx_PIN_9) must be configured in input mode.
0051 
0052       (#) Timers TRGO: TIM1, TIM2, TIM4, TIM5, TIM6, TIM7, TIM8, TIM15, TIM23 and TIM24
0053           (DAC_TRIGGER_T1_TRGO, DAC_TRIGGER_T2_TRGO...)
0054 
0055       (#) Low Power Timers TRGO: LPTIM1, LPTIM2 and LPTIM3
0056           (DAC_TRIGGER_LPTIM1_OUT, DAC_TRIGGER_LPTIM2_OUT)
0057 
0058       (#) High Resolution Timer TRGO: HRTIM1
0059           (DAC_TRIGGER_HR1_TRGO1, DAC_TRIGGER_HR1_TRGO2)
0060 
0061       (#) Software using DAC_TRIGGER_SOFTWARE
0062 
0063       *** DAC Buffer mode feature ***
0064       ===============================
0065       [..]
0066       Each DAC channel integrates an output buffer that can be used to
0067       reduce the output impedance, and to drive external loads directly
0068       without having to add an external operational amplifier.
0069       To enable, the output buffer use
0070       sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
0071       [..]
0072       (@) Refer to the device datasheet for more details about output
0073           impedance value with and without output buffer.
0074 
0075       *** GPIO configurations guidelines ***
0076       =====================
0077       [..]
0078       When a DAC channel is used (ex channel1 on PA4) and the other is not
0079       (ex channel2 on PA5 is configured in Analog and disabled).
0080       Channel1 may disturb channel2 as coupling effect.
0081       Note that there is no coupling on channel2 as soon as channel2 is turned on.
0082       Coupling on adjacent channel could be avoided as follows:
0083       when unused PA5 is configured as INPUT PULL-UP or DOWN.
0084       PA5 is configured in ANALOG just before it is turned on.
0085 
0086       *** DAC Sample and Hold feature ***
0087       ========================
0088       [..]
0089       For each converter, 2 modes are supported: normal mode and
0090       "sample and hold" mode (i.e. low power mode).
0091       In the sample and hold mode, the DAC core converts data, then holds the
0092       converted voltage on a capacitor. When not converting, the DAC cores and
0093       buffer are completely turned off between samples and the DAC output is
0094       tri-stated, therefore  reducing the overall power consumption. A new
0095       stabilization period is needed before each new conversion.
0096 
0097       The sample and hold allow setting internal or external voltage @
0098       low power consumption cost (output value can be at any given rate either
0099       by CPU or DMA).
0100 
0101       The Sample and hold block and registers uses either LSI & run in
0102       several power modes: run mode, sleep mode, low power run, low power sleep
0103       mode & stop1 mode.
0104 
0105       Low power stop1 mode allows only static conversion.
0106 
0107       To enable Sample and Hold mode
0108       Enable LSI using HAL_RCC_OscConfig with RCC_OSCILLATORTYPE_LSI &
0109       RCC_LSI_ON parameters.
0110 
0111       Use DAC_InitStructure.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_ENABLE;
0112          & DAC_ChannelConfTypeDef.DAC_SampleAndHoldConfig.DAC_SampleTime,
0113            DAC_HoldTime & DAC_RefreshTime;
0114 
0115        *** DAC calibration feature ***
0116        ===================================
0117       [..]
0118        (#)  The 2 converters (channel1 & channel2) provide calibration capabilities.
0119        (++) Calibration aims at correcting some offset of output buffer.
0120        (++) The DAC uses either factory calibration settings OR user defined
0121            calibration (trimming) settings (i.e. trimming mode).
0122        (++) The user defined settings can be figured out using self calibration
0123            handled by HAL_DACEx_SelfCalibrate.
0124        (++) HAL_DACEx_SelfCalibrate:
0125        (+++) Runs automatically the calibration.
0126        (+++) Enables the user trimming mode
0127        (+++) Updates a structure with trimming values with fresh calibration
0128             results.
0129             The user may store the calibration results for larger
0130             (ex monitoring the trimming as a function of temperature
0131             for instance)
0132 
0133        *** DAC wave generation feature ***
0134        ===================================
0135        [..]
0136        Both DAC channels can be used to generate
0137          (#) Noise wave
0138          (#) Triangle wave
0139 
0140        *** DAC data format ***
0141        =======================
0142        [..]
0143        The DAC data format can be:
0144          (#) 8-bit right alignment using DAC_ALIGN_8B_R
0145          (#) 12-bit left alignment using DAC_ALIGN_12B_L
0146          (#) 12-bit right alignment using DAC_ALIGN_12B_R
0147 
0148        *** DAC data value to voltage correspondence ***
0149        ================================================
0150        [..]
0151        The analog output voltage on each DAC channel pin is determined
0152        by the following equation:
0153        [..]
0154        DAC_OUTx = VREF+ * DOR / 4095
0155        (+) with  DOR is the Data Output Register
0156        [..]
0157           VREF+ is the input voltage reference (refer to the device datasheet)
0158        [..]
0159         e.g. To set DAC_OUT1 to 0.7V, use
0160        (+) Assuming that VREF+ = 3.3V, DAC_OUT1 = (3.3 * 868) / 4095 = 0.7V
0161 
0162        *** DMA requests ***
0163        =====================
0164        [..]
0165        A DMA request can be generated when an external trigger (but not a software trigger)
0166        occurs if DMA requests are enabled using HAL_DAC_Start_DMA().
0167        DMA requests are mapped as following:
0168       (#) DAC channel1: mapped on DMA_REQUEST_DAC1_CH1
0169       (#) DAC channel2: mapped on DMA_REQUEST_DAC1_CH2
0170 
0171      [..]
0172     (@) For Dual mode and specific signal (Triangle and noise) generation please
0173         refer to Extended Features Driver description
0174 
0175                       ##### How to use this driver #####
0176   ==============================================================================
0177     [..]
0178       (+) DAC APB clock must be enabled to get write access to DAC
0179           registers using HAL_DAC_Init()
0180       (+) Configure DAC_OUTx (DAC_OUT1: PA4, DAC_OUT2: PA5) in analog mode.
0181       (+) Configure the DAC channel using HAL_DAC_ConfigChannel() function.
0182       (+) Enable the DAC channel using HAL_DAC_Start() or HAL_DAC_Start_DMA() functions.
0183 
0184      *** Calibration mode IO operation ***
0185      ======================================
0186      [..]
0187        (+) Retrieve the factory trimming (calibration settings) using HAL_DACEx_GetTrimOffset()
0188        (+) Run the calibration using HAL_DACEx_SelfCalibrate()
0189        (+) Update the trimming while DAC running using HAL_DACEx_SetUserTrimming()
0190 
0191      *** Polling mode IO operation ***
0192      =================================
0193      [..]
0194        (+) Start the DAC peripheral using HAL_DAC_Start()
0195        (+) To read the DAC last data output value, use the HAL_DAC_GetValue() function.
0196        (+) Stop the DAC peripheral using HAL_DAC_Stop()
0197 
0198      *** DMA mode IO operation ***
0199      ==============================
0200      [..]
0201        (+) Start the DAC peripheral using HAL_DAC_Start_DMA(), at this stage the user specify the length
0202            of data to be transferred at each end of conversion
0203            First issued trigger will start the conversion of the value previously set by HAL_DAC_SetValue().
0204        (+) At the middle of data transfer HAL_DAC_ConvHalfCpltCallbackCh1() or HAL_DACEx_ConvHalfCpltCallbackCh2()
0205            function is executed and user can add his own code by customization of function pointer
0206            HAL_DAC_ConvHalfCpltCallbackCh1() or HAL_DACEx_ConvHalfCpltCallbackCh2()
0207        (+) At The end of data transfer HAL_DAC_ConvCpltCallbackCh1() or HAL_DACEx_ConvHalfCpltCallbackCh2()
0208            function is executed and user can add his own code by customization of function pointer
0209            HAL_DAC_ConvCpltCallbackCh1() or HAL_DACEx_ConvHalfCpltCallbackCh2()
0210        (+) In case of transfer Error, HAL_DAC_ErrorCallbackCh1() function is executed and user can
0211             add his own code by customization of function pointer HAL_DAC_ErrorCallbackCh1
0212        (+) In case of DMA underrun, DAC interruption triggers and execute internal function HAL_DAC_IRQHandler.
0213            HAL_DAC_DMAUnderrunCallbackCh1() or HAL_DACEx_DMAUnderrunCallbackCh2()
0214            function is executed and user can add his own code by customization of function pointer
0215            HAL_DAC_DMAUnderrunCallbackCh1() or HAL_DACEx_DMAUnderrunCallbackCh2() and
0216            add his own code by customization of function pointer HAL_DAC_ErrorCallbackCh1()
0217        (+) Stop the DAC peripheral using HAL_DAC_Stop_DMA()
0218 
0219     *** Callback registration ***
0220     =============================================
0221     [..]
0222       The compilation define  USE_HAL_DAC_REGISTER_CALLBACKS when set to 1
0223       allows the user to configure dynamically the driver callbacks.
0224 
0225     Use Functions HAL_DAC_RegisterCallback() to register a user callback,
0226       it allows to register following callbacks:
0227       (+) ConvCpltCallbackCh1     : callback when a half transfer is completed on Ch1.
0228       (+) ConvHalfCpltCallbackCh1 : callback when a transfer is completed on Ch1.
0229       (+) ErrorCallbackCh1        : callback when an error occurs on Ch1.
0230       (+) DMAUnderrunCallbackCh1  : callback when an underrun error occurs on Ch1.
0231       (+) ConvCpltCallbackCh2     : callback when a half transfer is completed on Ch2.
0232       (+) ConvHalfCpltCallbackCh2 : callback when a transfer is completed on Ch2.
0233       (+) ErrorCallbackCh2        : callback when an error occurs on Ch2.
0234       (+) DMAUnderrunCallbackCh2  : callback when an underrun error occurs on Ch2.
0235       (+) MspInitCallback         : DAC MspInit.
0236       (+) MspDeInitCallback       : DAC MspdeInit.
0237       This function takes as parameters the HAL peripheral handle, the Callback ID
0238       and a pointer to the user callback function.
0239 
0240     Use function HAL_DAC_UnRegisterCallback() to reset a callback to the default
0241       weak (overridden) function. It allows to reset following callbacks:
0242       (+) ConvCpltCallbackCh1     : callback when a half transfer is completed on Ch1.
0243       (+) ConvHalfCpltCallbackCh1 : callback when a transfer is completed on Ch1.
0244       (+) ErrorCallbackCh1        : callback when an error occurs on Ch1.
0245       (+) DMAUnderrunCallbackCh1  : callback when an underrun error occurs on Ch1.
0246       (+) ConvCpltCallbackCh2     : callback when a half transfer is completed on Ch2.
0247       (+) ConvHalfCpltCallbackCh2 : callback when a transfer is completed on Ch2.
0248       (+) ErrorCallbackCh2        : callback when an error occurs on Ch2.
0249       (+) DMAUnderrunCallbackCh2  : callback when an underrun error occurs on Ch2.
0250       (+) MspInitCallback         : DAC MspInit.
0251       (+) MspDeInitCallback       : DAC MspdeInit.
0252       (+) All Callbacks
0253       This function) takes as parameters the HAL peripheral handle and the Callback ID.
0254 
0255       By default, after the HAL_DAC_Init and if the state is HAL_DAC_STATE_RESET
0256       all callbacks are reset to the corresponding legacy weak (overridden) functions.
0257       Exception done for MspInit and MspDeInit callbacks that are respectively
0258       reset to the legacy weak (overridden) functions in the HAL_DAC_Init
0259       and  HAL_DAC_DeInit only when these callbacks are null (not registered beforehand).
0260       If not, MspInit or MspDeInit are not null, the HAL_DAC_Init and HAL_DAC_DeInit
0261       keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
0262 
0263       Callbacks can be registered/unregistered in READY state only.
0264       Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
0265       in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
0266       during the Init/DeInit.
0267       In that case first register the MspInit/MspDeInit user callbacks
0268       using HAL_DAC_RegisterCallback before calling HAL_DAC_DeInit
0269       or HAL_DAC_Init function.
0270 
0271       When The compilation define USE_HAL_DAC_REGISTER_CALLBACKS is set to 0 or
0272       not defined, the callback registering feature is not available
0273       and weak (overridden) callbacks are used.
0274 
0275      *** DAC HAL driver macros list ***
0276      =============================================
0277      [..]
0278        Below the list of most used macros in DAC HAL driver.
0279 
0280       (+) __HAL_DAC_ENABLE : Enable the DAC peripheral
0281       (+) __HAL_DAC_DISABLE : Disable the DAC peripheral
0282       (+) __HAL_DAC_CLEAR_FLAG: Clear the DAC's pending flags
0283       (+) __HAL_DAC_GET_FLAG: Get the selected DAC's flag status
0284 
0285      [..]
0286       (@) You can refer to the DAC HAL driver header file for more useful macros
0287 
0288 @endverbatim
0289   ******************************************************************************
0290   */
0291 
0292 /* Includes ------------------------------------------------------------------*/
0293 #include "stm32h7xx_hal.h"
0294 
0295 /** @addtogroup STM32H7xx_HAL_Driver
0296   * @{
0297   */
0298 
0299 #ifdef HAL_DAC_MODULE_ENABLED
0300 #if defined(DAC1) || defined(DAC2)
0301 
0302 /** @defgroup DAC DAC
0303   * @ingroup RTEMSBSPsARMSTM32H7
0304   * @brief DAC driver modules
0305   * @{
0306   */
0307 
0308 /* Private typedef -----------------------------------------------------------*/
0309 /* Private define ------------------------------------------------------------*/
0310 /* Private constants ---------------------------------------------------------*/
0311 /** @addtogroup DAC_Private_Constants DAC Private Constants
0312   * @{
0313   */
0314 #define TIMEOUT_DAC_CALIBCONFIG        1U         /* 1   ms        */
0315 
0316 /**
0317   * @}
0318   */
0319 
0320 /* Private macro -------------------------------------------------------------*/
0321 /* Private variables ---------------------------------------------------------*/
0322 /* Private function prototypes -----------------------------------------------*/
0323 /* Exported functions -------------------------------------------------------*/
0324 
0325 /** @defgroup DAC_Exported_Functions DAC Exported Functions
0326   * @ingroup RTEMSBSPsARMSTM32H7
0327   * @{
0328   */
0329 
0330 /** @defgroup DAC_Exported_Functions_Group1 Initialization and de-initialization functions
0331   * @ingroup RTEMSBSPsARMSTM32H7
0332   *  @brief    Initialization and Configuration functions
0333   *
0334 @verbatim
0335   ==============================================================================
0336               ##### Initialization and de-initialization functions #####
0337   ==============================================================================
0338     [..]  This section provides functions allowing to:
0339       (+) Initialize and configure the DAC.
0340       (+) De-initialize the DAC.
0341 
0342 @endverbatim
0343   * @{
0344   */
0345 
0346 /**
0347   * @brief  Initialize the DAC peripheral according to the specified parameters
0348   *         in the DAC_InitStruct and initialize the associated handle.
0349   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0350   *         the configuration information for the specified DAC.
0351   * @retval HAL status
0352   */
0353 HAL_StatusTypeDef HAL_DAC_Init(DAC_HandleTypeDef *hdac)
0354 {
0355   /* Check the DAC peripheral handle */
0356   if (hdac == NULL)
0357   {
0358     return HAL_ERROR;
0359   }
0360   /* Check the parameters */
0361   assert_param(IS_DAC_ALL_INSTANCE(hdac->Instance));
0362 
0363   if (hdac->State == HAL_DAC_STATE_RESET)
0364   {
0365 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
0366     /* Init the DAC Callback settings */
0367     hdac->ConvCpltCallbackCh1           = HAL_DAC_ConvCpltCallbackCh1;
0368     hdac->ConvHalfCpltCallbackCh1       = HAL_DAC_ConvHalfCpltCallbackCh1;
0369     hdac->ErrorCallbackCh1              = HAL_DAC_ErrorCallbackCh1;
0370     hdac->DMAUnderrunCallbackCh1        = HAL_DAC_DMAUnderrunCallbackCh1;
0371 
0372     hdac->ConvCpltCallbackCh2           = HAL_DACEx_ConvCpltCallbackCh2;
0373     hdac->ConvHalfCpltCallbackCh2       = HAL_DACEx_ConvHalfCpltCallbackCh2;
0374     hdac->ErrorCallbackCh2              = HAL_DACEx_ErrorCallbackCh2;
0375     hdac->DMAUnderrunCallbackCh2        = HAL_DACEx_DMAUnderrunCallbackCh2;
0376 
0377     if (hdac->MspInitCallback == NULL)
0378     {
0379       hdac->MspInitCallback             = HAL_DAC_MspInit;
0380     }
0381 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
0382 
0383     /* Allocate lock resource and initialize it */
0384     hdac->Lock = HAL_UNLOCKED;
0385 
0386 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
0387     /* Init the low level hardware */
0388     hdac->MspInitCallback(hdac);
0389 #else
0390     /* Init the low level hardware */
0391     HAL_DAC_MspInit(hdac);
0392 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
0393   }
0394 
0395   /* Initialize the DAC state*/
0396   hdac->State = HAL_DAC_STATE_BUSY;
0397 
0398   /* Set DAC error code to none */
0399   hdac->ErrorCode = HAL_DAC_ERROR_NONE;
0400 
0401   /* Initialize the DAC state*/
0402   hdac->State = HAL_DAC_STATE_READY;
0403 
0404   /* Return function status */
0405   return HAL_OK;
0406 }
0407 
0408 /**
0409   * @brief  Deinitialize the DAC peripheral registers to their default reset values.
0410   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0411   *         the configuration information for the specified DAC.
0412   * @retval HAL status
0413   */
0414 HAL_StatusTypeDef HAL_DAC_DeInit(DAC_HandleTypeDef *hdac)
0415 {
0416   /* Check the DAC peripheral handle */
0417   if (hdac == NULL)
0418   {
0419     return HAL_ERROR;
0420   }
0421 
0422   /* Check the parameters */
0423   assert_param(IS_DAC_ALL_INSTANCE(hdac->Instance));
0424 
0425   /* Change DAC state */
0426   hdac->State = HAL_DAC_STATE_BUSY;
0427 
0428 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
0429   if (hdac->MspDeInitCallback == NULL)
0430   {
0431     hdac->MspDeInitCallback = HAL_DAC_MspDeInit;
0432   }
0433   /* DeInit the low level hardware */
0434   hdac->MspDeInitCallback(hdac);
0435 #else
0436   /* DeInit the low level hardware */
0437   HAL_DAC_MspDeInit(hdac);
0438 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
0439 
0440   /* Set DAC error code to none */
0441   hdac->ErrorCode = HAL_DAC_ERROR_NONE;
0442 
0443   /* Change DAC state */
0444   hdac->State = HAL_DAC_STATE_RESET;
0445 
0446   /* Release Lock */
0447   __HAL_UNLOCK(hdac);
0448 
0449   /* Return function status */
0450   return HAL_OK;
0451 }
0452 
0453 /**
0454   * @brief  Initialize the DAC MSP.
0455   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0456   *         the configuration information for the specified DAC.
0457   * @retval None
0458   */
0459 __weak void HAL_DAC_MspInit(DAC_HandleTypeDef *hdac)
0460 {
0461   /* Prevent unused argument(s) compilation warning */
0462   UNUSED(hdac);
0463 
0464   /* NOTE : This function should not be modified, when the callback is needed,
0465             the HAL_DAC_MspInit could be implemented in the user file
0466    */
0467 }
0468 
0469 /**
0470   * @brief  DeInitialize the DAC MSP.
0471   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0472   *         the configuration information for the specified DAC.
0473   * @retval None
0474   */
0475 __weak void HAL_DAC_MspDeInit(DAC_HandleTypeDef *hdac)
0476 {
0477   /* Prevent unused argument(s) compilation warning */
0478   UNUSED(hdac);
0479 
0480   /* NOTE : This function should not be modified, when the callback is needed,
0481             the HAL_DAC_MspDeInit could be implemented in the user file
0482    */
0483 }
0484 
0485 /**
0486   * @}
0487   */
0488 
0489 /** @defgroup DAC_Exported_Functions_Group2 IO operation functions
0490   * @ingroup RTEMSBSPsARMSTM32H7
0491   *  @brief    IO operation functions
0492   *
0493 @verbatim
0494   ==============================================================================
0495              ##### IO operation functions #####
0496   ==============================================================================
0497     [..]  This section provides functions allowing to:
0498       (+) Start conversion.
0499       (+) Stop conversion.
0500       (+) Start conversion and enable DMA transfer.
0501       (+) Stop conversion and disable DMA transfer.
0502       (+) Get result of conversion.
0503 
0504 @endverbatim
0505   * @{
0506   */
0507 
0508 /**
0509   * @brief  Enables DAC and starts conversion of channel.
0510   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0511   *         the configuration information for the specified DAC.
0512   * @param  Channel The selected DAC channel.
0513   *          This parameter can be one of the following values:
0514   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
0515   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
0516   * @retval HAL status
0517   */
0518 HAL_StatusTypeDef HAL_DAC_Start(DAC_HandleTypeDef *hdac, uint32_t Channel)
0519 {
0520   /* Check the DAC peripheral handle */
0521   if (hdac == NULL)
0522   {
0523     return HAL_ERROR;
0524   }
0525 
0526   /* Check the parameters */
0527   assert_param(IS_DAC_CHANNEL(Channel));
0528 
0529   /* Process locked */
0530   __HAL_LOCK(hdac);
0531 
0532   /* Change DAC state */
0533   hdac->State = HAL_DAC_STATE_BUSY;
0534 
0535   /* Enable the Peripheral */
0536   __HAL_DAC_ENABLE(hdac, Channel);
0537 
0538   if (Channel == DAC_CHANNEL_1)
0539   {
0540     /* Check if software trigger enabled */
0541     if ((hdac->Instance->CR & (DAC_CR_TEN1 | DAC_CR_TSEL1)) == DAC_TRIGGER_SOFTWARE)
0542     {
0543       /* Enable the selected DAC software conversion */
0544       SET_BIT(hdac->Instance->SWTRIGR, DAC_SWTRIGR_SWTRIG1);
0545     }
0546   }
0547 
0548   else
0549   {
0550     /* Check if software trigger enabled */
0551     if ((hdac->Instance->CR & (DAC_CR_TEN2 | DAC_CR_TSEL2)) == (DAC_TRIGGER_SOFTWARE << (Channel & 0x10UL)))
0552     {
0553       /* Enable the selected DAC software conversion*/
0554       SET_BIT(hdac->Instance->SWTRIGR, DAC_SWTRIGR_SWTRIG2);
0555     }
0556   }
0557 
0558 
0559   /* Change DAC state */
0560   hdac->State = HAL_DAC_STATE_READY;
0561 
0562   /* Process unlocked */
0563   __HAL_UNLOCK(hdac);
0564 
0565   /* Return function status */
0566   return HAL_OK;
0567 }
0568 
0569 /**
0570   * @brief  Disables DAC and stop conversion of channel.
0571   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0572   *         the configuration information for the specified DAC.
0573   * @param  Channel The selected DAC channel.
0574   *          This parameter can be one of the following values:
0575   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
0576   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
0577   * @retval HAL status
0578   */
0579 HAL_StatusTypeDef HAL_DAC_Stop(DAC_HandleTypeDef *hdac, uint32_t Channel)
0580 {
0581   /* Check the DAC peripheral handle */
0582   if (hdac == NULL)
0583   {
0584     return HAL_ERROR;
0585   }
0586 
0587   /* Check the parameters */
0588   assert_param(IS_DAC_CHANNEL(Channel));
0589 
0590   /* Disable the Peripheral */
0591   __HAL_DAC_DISABLE(hdac, Channel);
0592 
0593   /* Change DAC state */
0594   hdac->State = HAL_DAC_STATE_READY;
0595 
0596   /* Return function status */
0597   return HAL_OK;
0598 }
0599 
0600 /**
0601   * @brief  Enables DAC and starts conversion of channel.
0602   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0603   *         the configuration information for the specified DAC.
0604   * @param  Channel The selected DAC channel.
0605   *          This parameter can be one of the following values:
0606   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
0607   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
0608   * @param  pData The source Buffer address.
0609   * @param  Length The length of data to be transferred from memory to DAC peripheral
0610   * @param  Alignment Specifies the data alignment for DAC channel.
0611   *          This parameter can be one of the following values:
0612   *            @arg DAC_ALIGN_8B_R: 8bit right data alignment selected
0613   *            @arg DAC_ALIGN_12B_L: 12bit left data alignment selected
0614   *            @arg DAC_ALIGN_12B_R: 12bit right data alignment selected
0615   * @retval HAL status
0616   */
0617 HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel, const uint32_t *pData, uint32_t Length,
0618                                     uint32_t Alignment)
0619 {
0620   HAL_StatusTypeDef status;
0621   uint32_t tmpreg;
0622 
0623   /* Check the DAC peripheral handle */
0624   if (hdac == NULL)
0625   {
0626     return HAL_ERROR;
0627   }
0628 
0629   /* Check the parameters */
0630   assert_param(IS_DAC_CHANNEL(Channel));
0631   assert_param(IS_DAC_ALIGN(Alignment));
0632 
0633   /* Process locked */
0634   __HAL_LOCK(hdac);
0635 
0636   /* Change DAC state */
0637   hdac->State = HAL_DAC_STATE_BUSY;
0638 
0639   if (Channel == DAC_CHANNEL_1)
0640   {
0641     /* Set the DMA transfer complete callback for channel1 */
0642     hdac->DMA_Handle1->XferCpltCallback = DAC_DMAConvCpltCh1;
0643 
0644     /* Set the DMA half transfer complete callback for channel1 */
0645     hdac->DMA_Handle1->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh1;
0646 
0647     /* Set the DMA error callback for channel1 */
0648     hdac->DMA_Handle1->XferErrorCallback = DAC_DMAErrorCh1;
0649 
0650     /* Enable the selected DAC channel1 DMA request */
0651     SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN1);
0652 
0653     /* Case of use of channel 1 */
0654     switch (Alignment)
0655     {
0656       case DAC_ALIGN_12B_R:
0657         /* Get DHR12R1 address */
0658         tmpreg = (uint32_t)&hdac->Instance->DHR12R1;
0659         break;
0660       case DAC_ALIGN_12B_L:
0661         /* Get DHR12L1 address */
0662         tmpreg = (uint32_t)&hdac->Instance->DHR12L1;
0663         break;
0664       default: /* case DAC_ALIGN_8B_R */
0665         /* Get DHR8R1 address */
0666         tmpreg = (uint32_t)&hdac->Instance->DHR8R1;
0667         break;
0668     }
0669   }
0670 
0671   else
0672   {
0673     /* Set the DMA transfer complete callback for channel2 */
0674     hdac->DMA_Handle2->XferCpltCallback = DAC_DMAConvCpltCh2;
0675 
0676     /* Set the DMA half transfer complete callback for channel2 */
0677     hdac->DMA_Handle2->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh2;
0678 
0679     /* Set the DMA error callback for channel2 */
0680     hdac->DMA_Handle2->XferErrorCallback = DAC_DMAErrorCh2;
0681 
0682     /* Enable the selected DAC channel2 DMA request */
0683     SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN2);
0684 
0685     /* Case of use of channel 2 */
0686     switch (Alignment)
0687     {
0688       case DAC_ALIGN_12B_R:
0689         /* Get DHR12R2 address */
0690         tmpreg = (uint32_t)&hdac->Instance->DHR12R2;
0691         break;
0692       case DAC_ALIGN_12B_L:
0693         /* Get DHR12L2 address */
0694         tmpreg = (uint32_t)&hdac->Instance->DHR12L2;
0695         break;
0696       default: /* case DAC_ALIGN_8B_R */
0697         /* Get DHR8R2 address */
0698         tmpreg = (uint32_t)&hdac->Instance->DHR8R2;
0699         break;
0700     }
0701   }
0702 
0703   if (Channel == DAC_CHANNEL_1)
0704   {
0705     /* Enable the DAC DMA underrun interrupt */
0706     __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR1);
0707 
0708     /* Enable the DMA Stream */
0709     status = HAL_DMA_Start_IT(hdac->DMA_Handle1, (uint32_t)pData, tmpreg, Length);
0710   }
0711 
0712   else
0713   {
0714     /* Enable the DAC DMA underrun interrupt */
0715     __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR2);
0716 
0717     /* Enable the DMA Stream */
0718     status = HAL_DMA_Start_IT(hdac->DMA_Handle2, (uint32_t)pData, tmpreg, Length);
0719   }
0720 
0721 
0722   /* Process Unlocked */
0723   __HAL_UNLOCK(hdac);
0724 
0725   if (status == HAL_OK)
0726   {
0727     /* Enable the Peripheral */
0728     __HAL_DAC_ENABLE(hdac, Channel);
0729   }
0730   else
0731   {
0732     hdac->ErrorCode |= HAL_DAC_ERROR_DMA;
0733   }
0734 
0735   /* Return function status */
0736   return status;
0737 }
0738 
0739 /**
0740   * @brief  Disables DAC and stop conversion of channel.
0741   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0742   *         the configuration information for the specified DAC.
0743   * @param  Channel The selected DAC channel.
0744   *          This parameter can be one of the following values:
0745   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
0746   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
0747   * @retval HAL status
0748   */
0749 HAL_StatusTypeDef HAL_DAC_Stop_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel)
0750 {
0751   /* Check the DAC peripheral handle */
0752   if (hdac == NULL)
0753   {
0754     return HAL_ERROR;
0755   }
0756 
0757   /* Check the parameters */
0758   assert_param(IS_DAC_CHANNEL(Channel));
0759 
0760   /* Disable the selected DAC channel DMA request */
0761   hdac->Instance->CR &= ~(DAC_CR_DMAEN1 << (Channel & 0x10UL));
0762 
0763   /* Disable the Peripheral */
0764   __HAL_DAC_DISABLE(hdac, Channel);
0765 
0766   /* Disable the DMA Stream */
0767 
0768   /* Channel1 is used */
0769   if (Channel == DAC_CHANNEL_1)
0770   {
0771     /* Disable the DMA Stream */
0772     (void)HAL_DMA_Abort(hdac->DMA_Handle1);
0773 
0774     /* Disable the DAC DMA underrun interrupt */
0775     __HAL_DAC_DISABLE_IT(hdac, DAC_IT_DMAUDR1);
0776   }
0777 
0778   else /* Channel2 is used for */
0779   {
0780     /* Disable the DMA Stream */
0781     (void)HAL_DMA_Abort(hdac->DMA_Handle2);
0782 
0783     /* Disable the DAC DMA underrun interrupt */
0784     __HAL_DAC_DISABLE_IT(hdac, DAC_IT_DMAUDR2);
0785   }
0786 
0787 
0788   /* Change DAC state */
0789   hdac->State = HAL_DAC_STATE_READY;
0790 
0791   /* Return function status */
0792   return HAL_OK;
0793 }
0794 
0795 /**
0796   * @brief  Handles DAC interrupt request
0797   *         This function uses the interruption of DMA
0798   *         underrun.
0799   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0800   *         the configuration information for the specified DAC.
0801   * @retval None
0802   */
0803 void HAL_DAC_IRQHandler(DAC_HandleTypeDef *hdac)
0804 {
0805   uint32_t itsource = hdac->Instance->CR;
0806   uint32_t itflag   = hdac->Instance->SR;
0807 
0808   if ((itsource & DAC_IT_DMAUDR1) == DAC_IT_DMAUDR1)
0809   {
0810     /* Check underrun flag of DAC channel 1 */
0811     if ((itflag & DAC_FLAG_DMAUDR1) == DAC_FLAG_DMAUDR1)
0812     {
0813       /* Change DAC state to error state */
0814       hdac->State = HAL_DAC_STATE_ERROR;
0815 
0816       /* Set DAC error code to channel1 DMA underrun error */
0817       SET_BIT(hdac->ErrorCode, HAL_DAC_ERROR_DMAUNDERRUNCH1);
0818 
0819       /* Clear the underrun flag */
0820       __HAL_DAC_CLEAR_FLAG(hdac, DAC_FLAG_DMAUDR1);
0821 
0822       /* Disable the selected DAC channel1 DMA request */
0823       __HAL_DAC_DISABLE_IT(hdac, DAC_CR_DMAEN1);
0824 
0825       /* Error callback */
0826 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
0827       hdac->DMAUnderrunCallbackCh1(hdac);
0828 #else
0829       HAL_DAC_DMAUnderrunCallbackCh1(hdac);
0830 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
0831     }
0832   }
0833 
0834 
0835   if ((itsource & DAC_IT_DMAUDR2) == DAC_IT_DMAUDR2)
0836   {
0837     /* Check underrun flag of DAC channel 2 */
0838     if ((itflag & DAC_FLAG_DMAUDR2) == DAC_FLAG_DMAUDR2)
0839     {
0840       /* Change DAC state to error state */
0841       hdac->State = HAL_DAC_STATE_ERROR;
0842 
0843       /* Set DAC error code to channel2 DMA underrun error */
0844       SET_BIT(hdac->ErrorCode, HAL_DAC_ERROR_DMAUNDERRUNCH2);
0845 
0846       /* Clear the underrun flag */
0847       __HAL_DAC_CLEAR_FLAG(hdac, DAC_FLAG_DMAUDR2);
0848 
0849       /* Disable the selected DAC channel2 DMA request */
0850       __HAL_DAC_DISABLE_IT(hdac, DAC_CR_DMAEN2);
0851 
0852       /* Error callback */
0853 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
0854       hdac->DMAUnderrunCallbackCh2(hdac);
0855 #else
0856       HAL_DACEx_DMAUnderrunCallbackCh2(hdac);
0857 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
0858     }
0859   }
0860 
0861 }
0862 
0863 /**
0864   * @brief  Set the specified data holding register value for DAC channel.
0865   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0866   *         the configuration information for the specified DAC.
0867   * @param  Channel The selected DAC channel.
0868   *          This parameter can be one of the following values:
0869   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
0870   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
0871   * @param  Alignment Specifies the data alignment.
0872   *          This parameter can be one of the following values:
0873   *            @arg DAC_ALIGN_8B_R: 8bit right data alignment selected
0874   *            @arg DAC_ALIGN_12B_L: 12bit left data alignment selected
0875   *            @arg DAC_ALIGN_12B_R: 12bit right data alignment selected
0876   * @param  Data Data to be loaded in the selected data holding register.
0877   * @retval HAL status
0878   */
0879 HAL_StatusTypeDef HAL_DAC_SetValue(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data)
0880 {
0881   __IO uint32_t tmp = 0UL;
0882 
0883   /* Check the DAC peripheral handle */
0884   if (hdac == NULL)
0885   {
0886     return HAL_ERROR;
0887   }
0888 
0889   /* Check the parameters */
0890   assert_param(IS_DAC_CHANNEL(Channel));
0891   assert_param(IS_DAC_ALIGN(Alignment));
0892   assert_param(IS_DAC_DATA(Data));
0893 
0894   tmp = (uint32_t)hdac->Instance;
0895   if (Channel == DAC_CHANNEL_1)
0896   {
0897     tmp += DAC_DHR12R1_ALIGNMENT(Alignment);
0898   }
0899 
0900   else
0901   {
0902     tmp += DAC_DHR12R2_ALIGNMENT(Alignment);
0903   }
0904 
0905 
0906   /* Set the DAC channel selected data holding register */
0907   *(__IO uint32_t *) tmp = Data;
0908 
0909   /* Return function status */
0910   return HAL_OK;
0911 }
0912 
0913 /**
0914   * @brief  Conversion complete callback in non-blocking mode for Channel1
0915   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0916   *         the configuration information for the specified DAC.
0917   * @retval None
0918   */
0919 __weak void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef *hdac)
0920 {
0921   /* Prevent unused argument(s) compilation warning */
0922   UNUSED(hdac);
0923 
0924   /* NOTE : This function should not be modified, when the callback is needed,
0925             the HAL_DAC_ConvCpltCallbackCh1 could be implemented in the user file
0926    */
0927 }
0928 
0929 /**
0930   * @brief  Conversion half DMA transfer callback in non-blocking mode for Channel1
0931   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0932   *         the configuration information for the specified DAC.
0933   * @retval None
0934   */
0935 __weak void HAL_DAC_ConvHalfCpltCallbackCh1(DAC_HandleTypeDef *hdac)
0936 {
0937   /* Prevent unused argument(s) compilation warning */
0938   UNUSED(hdac);
0939 
0940   /* NOTE : This function should not be modified, when the callback is needed,
0941             the HAL_DAC_ConvHalfCpltCallbackCh1 could be implemented in the user file
0942    */
0943 }
0944 
0945 /**
0946   * @brief  Error DAC callback for Channel1.
0947   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0948   *         the configuration information for the specified DAC.
0949   * @retval None
0950   */
0951 __weak void HAL_DAC_ErrorCallbackCh1(DAC_HandleTypeDef *hdac)
0952 {
0953   /* Prevent unused argument(s) compilation warning */
0954   UNUSED(hdac);
0955 
0956   /* NOTE : This function should not be modified, when the callback is needed,
0957             the HAL_DAC_ErrorCallbackCh1 could be implemented in the user file
0958    */
0959 }
0960 
0961 /**
0962   * @brief  DMA underrun DAC callback for channel1.
0963   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0964   *         the configuration information for the specified DAC.
0965   * @retval None
0966   */
0967 __weak void HAL_DAC_DMAUnderrunCallbackCh1(DAC_HandleTypeDef *hdac)
0968 {
0969   /* Prevent unused argument(s) compilation warning */
0970   UNUSED(hdac);
0971 
0972   /* NOTE : This function should not be modified, when the callback is needed,
0973             the HAL_DAC_DMAUnderrunCallbackCh1 could be implemented in the user file
0974    */
0975 }
0976 
0977 /**
0978   * @}
0979   */
0980 
0981 /** @defgroup DAC_Exported_Functions_Group3 Peripheral Control functions
0982   * @ingroup RTEMSBSPsARMSTM32H7
0983   *  @brief    Peripheral Control functions
0984   *
0985 @verbatim
0986   ==============================================================================
0987              ##### Peripheral Control functions #####
0988   ==============================================================================
0989     [..]  This section provides functions allowing to:
0990       (+) Configure channels.
0991       (+) Set the specified data holding register value for DAC channel.
0992 
0993 @endverbatim
0994   * @{
0995   */
0996 
0997 /**
0998   * @brief  Returns the last data output value of the selected DAC channel.
0999   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
1000   *         the configuration information for the specified DAC.
1001   * @param  Channel The selected DAC channel.
1002   *          This parameter can be one of the following values:
1003   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
1004   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
1005   * @retval The selected DAC channel data output value.
1006   */
1007 uint32_t HAL_DAC_GetValue(const DAC_HandleTypeDef *hdac, uint32_t Channel)
1008 {
1009   uint32_t result;
1010 
1011   /* Check the DAC peripheral handle */
1012   assert_param(hdac != NULL);
1013 
1014   /* Check the parameters */
1015   assert_param(IS_DAC_CHANNEL(Channel));
1016 
1017   if (Channel == DAC_CHANNEL_1)
1018   {
1019     result = hdac->Instance->DOR1;
1020   }
1021 
1022   else
1023   {
1024     result = hdac->Instance->DOR2;
1025   }
1026 
1027   /* Returns the DAC channel data output register value */
1028   return result;
1029 }
1030 
1031 /**
1032   * @brief  Configures the selected DAC channel.
1033   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
1034   *         the configuration information for the specified DAC.
1035   * @param  sConfig DAC configuration structure.
1036   * @param  Channel The selected DAC channel.
1037   *          This parameter can be one of the following values:
1038   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
1039   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
1040   * @retval HAL status
1041   */
1042 HAL_StatusTypeDef HAL_DAC_ConfigChannel(DAC_HandleTypeDef *hdac,
1043                                         const DAC_ChannelConfTypeDef *sConfig, uint32_t Channel)
1044 {
1045   HAL_StatusTypeDef status = HAL_OK;
1046   uint32_t tmpreg1;
1047   uint32_t tmpreg2;
1048   uint32_t tickstart;
1049   uint32_t connectOnChip;
1050 
1051   /* Check the DAC peripheral handle and channel configuration struct */
1052   if ((hdac == NULL) || (sConfig == NULL))
1053   {
1054     return HAL_ERROR;
1055   }
1056 
1057   /* Check the DAC parameters */
1058   assert_param(IS_DAC_TRIGGER(sConfig->DAC_Trigger));
1059   assert_param(IS_DAC_OUTPUT_BUFFER_STATE(sConfig->DAC_OutputBuffer));
1060   assert_param(IS_DAC_CHIP_CONNECTION(sConfig->DAC_ConnectOnChipPeripheral));
1061   assert_param(IS_DAC_TRIMMING(sConfig->DAC_UserTrimming));
1062   if ((sConfig->DAC_UserTrimming) == DAC_TRIMMING_USER)
1063   {
1064     assert_param(IS_DAC_TRIMMINGVALUE(sConfig->DAC_TrimmingValue));
1065   }
1066   assert_param(IS_DAC_SAMPLEANDHOLD(sConfig->DAC_SampleAndHold));
1067   if ((sConfig->DAC_SampleAndHold) == DAC_SAMPLEANDHOLD_ENABLE)
1068   {
1069     assert_param(IS_DAC_SAMPLETIME(sConfig->DAC_SampleAndHoldConfig.DAC_SampleTime));
1070     assert_param(IS_DAC_HOLDTIME(sConfig->DAC_SampleAndHoldConfig.DAC_HoldTime));
1071     assert_param(IS_DAC_REFRESHTIME(sConfig->DAC_SampleAndHoldConfig.DAC_RefreshTime));
1072   }
1073   assert_param(IS_DAC_CHANNEL(Channel));
1074 
1075   /* Process locked */
1076   __HAL_LOCK(hdac);
1077 
1078   /* Change DAC state */
1079   hdac->State = HAL_DAC_STATE_BUSY;
1080 
1081   /* Sample and hold configuration */
1082   if (sConfig->DAC_SampleAndHold == DAC_SAMPLEANDHOLD_ENABLE)
1083   {
1084     /* Get timeout */
1085     tickstart = HAL_GetTick();
1086 
1087     if (Channel == DAC_CHANNEL_1)
1088     {
1089       /* SHSR1 can be written when BWST1 is cleared */
1090       while (((hdac->Instance->SR) & DAC_SR_BWST1) != 0UL)
1091       {
1092         /* Check for the Timeout */
1093         if ((HAL_GetTick() - tickstart) > TIMEOUT_DAC_CALIBCONFIG)
1094         {
1095           /* New check to avoid false timeout detection in case of preemption */
1096           if (((hdac->Instance->SR) & DAC_SR_BWST1) != 0UL)
1097           {
1098             /* Update error code */
1099             SET_BIT(hdac->ErrorCode, HAL_DAC_ERROR_TIMEOUT);
1100 
1101             /* Change the DMA state */
1102             hdac->State = HAL_DAC_STATE_TIMEOUT;
1103 
1104             return HAL_TIMEOUT;
1105           }
1106         }
1107       }
1108       hdac->Instance->SHSR1 = sConfig->DAC_SampleAndHoldConfig.DAC_SampleTime;
1109     }
1110 
1111     else /* Channel 2 */
1112     {
1113       /* SHSR2 can be written when BWST2 is cleared */
1114       while (((hdac->Instance->SR) & DAC_SR_BWST2) != 0UL)
1115       {
1116         /* Check for the Timeout */
1117         if ((HAL_GetTick() - tickstart) > TIMEOUT_DAC_CALIBCONFIG)
1118         {
1119           /* New check to avoid false timeout detection in case of preemption */
1120           if (((hdac->Instance->SR) & DAC_SR_BWST2) != 0UL)
1121           {
1122             /* Update error code */
1123             SET_BIT(hdac->ErrorCode, HAL_DAC_ERROR_TIMEOUT);
1124 
1125             /* Change the DMA state */
1126             hdac->State = HAL_DAC_STATE_TIMEOUT;
1127 
1128             return HAL_TIMEOUT;
1129           }
1130         }
1131       }
1132       hdac->Instance->SHSR2 = sConfig->DAC_SampleAndHoldConfig.DAC_SampleTime;
1133     }
1134 
1135 
1136     /* HoldTime */
1137     MODIFY_REG(hdac->Instance->SHHR, DAC_SHHR_THOLD1 << (Channel & 0x10UL),
1138                (sConfig->DAC_SampleAndHoldConfig.DAC_HoldTime) << (Channel & 0x10UL));
1139     /* RefreshTime */
1140     MODIFY_REG(hdac->Instance->SHRR, DAC_SHRR_TREFRESH1 << (Channel & 0x10UL),
1141                (sConfig->DAC_SampleAndHoldConfig.DAC_RefreshTime) << (Channel & 0x10UL));
1142   }
1143 
1144   if (sConfig->DAC_UserTrimming == DAC_TRIMMING_USER)
1145     /* USER TRIMMING */
1146   {
1147     /* Get the DAC CCR value */
1148     tmpreg1 = hdac->Instance->CCR;
1149     /* Clear trimming value */
1150     tmpreg1 &= ~(((uint32_t)(DAC_CCR_OTRIM1)) << (Channel & 0x10UL));
1151     /* Configure for the selected trimming offset */
1152     tmpreg2 = sConfig->DAC_TrimmingValue;
1153     /* Calculate CCR register value depending on DAC_Channel */
1154     tmpreg1 |= tmpreg2 << (Channel & 0x10UL);
1155     /* Write to DAC CCR */
1156     hdac->Instance->CCR = tmpreg1;
1157   }
1158   /* else factory trimming is used (factory setting are available at reset)*/
1159   /* SW Nothing has nothing to do */
1160 
1161   /* Get the DAC MCR value */
1162   tmpreg1 = hdac->Instance->MCR;
1163   /* Clear DAC_MCR_MODEx bits */
1164   tmpreg1 &= ~(((uint32_t)(DAC_MCR_MODE1)) << (Channel & 0x10UL));
1165   /* Configure for the selected DAC channel: mode, buffer output & on chip peripheral connect */
1166 
1167 
1168   if (sConfig->DAC_ConnectOnChipPeripheral == DAC_CHIPCONNECT_EXTERNAL)
1169   {
1170     connectOnChip = 0x00000000UL;
1171   }
1172   else if (sConfig->DAC_ConnectOnChipPeripheral == DAC_CHIPCONNECT_INTERNAL)
1173   {
1174     connectOnChip = DAC_MCR_MODE1_0;
1175   }
1176   else /* (sConfig->DAC_ConnectOnChipPeripheral == DAC_CHIPCONNECT_BOTH) */
1177   {
1178     if (sConfig->DAC_OutputBuffer == DAC_OUTPUTBUFFER_ENABLE)
1179     {
1180       connectOnChip = DAC_MCR_MODE1_0;
1181     }
1182     else
1183     {
1184       connectOnChip = 0x00000000UL;
1185     }
1186   }
1187   tmpreg2 = (sConfig->DAC_SampleAndHold | sConfig->DAC_OutputBuffer | connectOnChip);
1188   /* Calculate MCR register value depending on DAC_Channel */
1189   tmpreg1 |= tmpreg2 << (Channel & 0x10UL);
1190   /* Write to DAC MCR */
1191   hdac->Instance->MCR = tmpreg1;
1192 
1193   /* DAC in normal operating mode hence clear DAC_CR_CENx bit */
1194   CLEAR_BIT(hdac->Instance->CR, DAC_CR_CEN1 << (Channel & 0x10UL));
1195 
1196   /* Get the DAC CR value */
1197   tmpreg1 = hdac->Instance->CR;
1198   /* Clear TENx, TSELx, WAVEx and MAMPx bits */
1199   tmpreg1 &= ~(((uint32_t)(DAC_CR_MAMP1 | DAC_CR_WAVE1 | DAC_CR_TSEL1 | DAC_CR_TEN1)) << (Channel & 0x10UL));
1200   /* Configure for the selected DAC channel: trigger */
1201   /* Set TSELx and TENx bits according to DAC_Trigger value */
1202   tmpreg2 = sConfig->DAC_Trigger;
1203   /* Calculate CR register value depending on DAC_Channel */
1204   tmpreg1 |= tmpreg2 << (Channel & 0x10UL);
1205   /* Write to DAC CR */
1206   hdac->Instance->CR = tmpreg1;
1207   /* Disable wave generation */
1208   CLEAR_BIT(hdac->Instance->CR, (DAC_CR_WAVE1 << (Channel & 0x10UL)));
1209 
1210   /* Change DAC state */
1211   hdac->State = HAL_DAC_STATE_READY;
1212 
1213   /* Process unlocked */
1214   __HAL_UNLOCK(hdac);
1215 
1216   /* Return function status */
1217   return status;
1218 }
1219 
1220 /**
1221   * @}
1222   */
1223 
1224 /** @defgroup DAC_Exported_Functions_Group4 Peripheral State and Errors functions
1225   * @ingroup RTEMSBSPsARMSTM32H7
1226   *  @brief   Peripheral State and Errors functions
1227   *
1228 @verbatim
1229   ==============================================================================
1230             ##### Peripheral State and Errors functions #####
1231   ==============================================================================
1232     [..]
1233     This subsection provides functions allowing to
1234       (+) Check the DAC state.
1235       (+) Check the DAC Errors.
1236 
1237 @endverbatim
1238   * @{
1239   */
1240 
1241 /**
1242   * @brief  return the DAC handle state
1243   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
1244   *         the configuration information for the specified DAC.
1245   * @retval HAL state
1246   */
1247 HAL_DAC_StateTypeDef HAL_DAC_GetState(const DAC_HandleTypeDef *hdac)
1248 {
1249   /* Return DAC handle state */
1250   return hdac->State;
1251 }
1252 
1253 
1254 /**
1255   * @brief  Return the DAC error code
1256   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
1257   *         the configuration information for the specified DAC.
1258   * @retval DAC Error Code
1259   */
1260 uint32_t HAL_DAC_GetError(const DAC_HandleTypeDef *hdac)
1261 {
1262   return hdac->ErrorCode;
1263 }
1264 
1265 /**
1266   * @}
1267   */
1268 
1269 /**
1270   * @}
1271   */
1272 
1273 /** @addtogroup DAC_Exported_Functions
1274   * @{
1275   */
1276 
1277 /** @addtogroup DAC_Exported_Functions_Group1
1278   * @{
1279   */
1280 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
1281 /**
1282   * @brief  Register a User DAC Callback
1283   *         To be used instead of the weak (overridden) predefined callback
1284   * @note   The HAL_DAC_RegisterCallback() may be called before HAL_DAC_Init() in HAL_DAC_STATE_RESET to register
1285   *         callbacks for HAL_DAC_MSPINIT_CB_ID and HAL_DAC_MSPDEINIT_CB_ID
1286   * @param  hdac DAC handle
1287   * @param  CallbackID ID of the callback to be registered
1288   *         This parameter can be one of the following values:
1289   *          @arg @ref HAL_DAC_ERROR_INVALID_CALLBACK   DAC Error Callback ID
1290   *          @arg @ref HAL_DAC_CH1_COMPLETE_CB_ID       DAC CH1 Complete Callback ID
1291   *          @arg @ref HAL_DAC_CH1_HALF_COMPLETE_CB_ID  DAC CH1 Half Complete Callback ID
1292   *          @arg @ref HAL_DAC_CH1_ERROR_ID             DAC CH1 Error Callback ID
1293   *          @arg @ref HAL_DAC_CH1_UNDERRUN_CB_ID       DAC CH1 UnderRun Callback ID
1294   *          @arg @ref HAL_DAC_CH2_COMPLETE_CB_ID       DAC CH2 Complete Callback ID
1295   *          @arg @ref HAL_DAC_CH2_HALF_COMPLETE_CB_ID  DAC CH2 Half Complete Callback ID
1296   *          @arg @ref HAL_DAC_CH2_ERROR_ID             DAC CH2 Error Callback ID
1297   *          @arg @ref HAL_DAC_CH2_UNDERRUN_CB_ID       DAC CH2 UnderRun Callback ID
1298   *          @arg @ref HAL_DAC_MSPINIT_CB_ID            DAC MSP Init Callback ID
1299   *          @arg @ref HAL_DAC_MSPDEINIT_CB_ID          DAC MSP DeInit Callback ID
1300   *
1301   * @param  pCallback pointer to the Callback function
1302   * @retval status
1303   */
1304 HAL_StatusTypeDef HAL_DAC_RegisterCallback(DAC_HandleTypeDef *hdac, HAL_DAC_CallbackIDTypeDef CallbackID,
1305                                            pDAC_CallbackTypeDef pCallback)
1306 {
1307   HAL_StatusTypeDef status = HAL_OK;
1308 
1309   /* Check the DAC peripheral handle */
1310   if (hdac == NULL)
1311   {
1312     return HAL_ERROR;
1313   }
1314 
1315   if (pCallback == NULL)
1316   {
1317     /* Update the error code */
1318     hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK;
1319     return HAL_ERROR;
1320   }
1321 
1322   if (hdac->State == HAL_DAC_STATE_READY)
1323   {
1324     switch (CallbackID)
1325     {
1326       case HAL_DAC_CH1_COMPLETE_CB_ID :
1327         hdac->ConvCpltCallbackCh1 = pCallback;
1328         break;
1329       case HAL_DAC_CH1_HALF_COMPLETE_CB_ID :
1330         hdac->ConvHalfCpltCallbackCh1 = pCallback;
1331         break;
1332       case HAL_DAC_CH1_ERROR_ID :
1333         hdac->ErrorCallbackCh1 = pCallback;
1334         break;
1335       case HAL_DAC_CH1_UNDERRUN_CB_ID :
1336         hdac->DMAUnderrunCallbackCh1 = pCallback;
1337         break;
1338 
1339       case HAL_DAC_CH2_COMPLETE_CB_ID :
1340         hdac->ConvCpltCallbackCh2 = pCallback;
1341         break;
1342       case HAL_DAC_CH2_HALF_COMPLETE_CB_ID :
1343         hdac->ConvHalfCpltCallbackCh2 = pCallback;
1344         break;
1345       case HAL_DAC_CH2_ERROR_ID :
1346         hdac->ErrorCallbackCh2 = pCallback;
1347         break;
1348       case HAL_DAC_CH2_UNDERRUN_CB_ID :
1349         hdac->DMAUnderrunCallbackCh2 = pCallback;
1350         break;
1351 
1352       case HAL_DAC_MSPINIT_CB_ID :
1353         hdac->MspInitCallback = pCallback;
1354         break;
1355       case HAL_DAC_MSPDEINIT_CB_ID :
1356         hdac->MspDeInitCallback = pCallback;
1357         break;
1358       default :
1359         /* Update the error code */
1360         hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK;
1361         /* update return status */
1362         status =  HAL_ERROR;
1363         break;
1364     }
1365   }
1366   else if (hdac->State == HAL_DAC_STATE_RESET)
1367   {
1368     switch (CallbackID)
1369     {
1370       case HAL_DAC_MSPINIT_CB_ID :
1371         hdac->MspInitCallback = pCallback;
1372         break;
1373       case HAL_DAC_MSPDEINIT_CB_ID :
1374         hdac->MspDeInitCallback = pCallback;
1375         break;
1376       default :
1377         /* Update the error code */
1378         hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK;
1379         /* update return status */
1380         status =  HAL_ERROR;
1381         break;
1382     }
1383   }
1384   else
1385   {
1386     /* Update the error code */
1387     hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK;
1388     /* update return status */
1389     status =  HAL_ERROR;
1390   }
1391 
1392   return status;
1393 }
1394 
1395 /**
1396   * @brief  Unregister a User DAC Callback
1397   *         DAC Callback is redirected to the weak (overridden) predefined callback
1398   * @note   The HAL_DAC_UnRegisterCallback() may be called before HAL_DAC_Init() in HAL_DAC_STATE_RESET to un-register
1399   *         callbacks for HAL_DAC_MSPINIT_CB_ID and HAL_DAC_MSPDEINIT_CB_ID
1400   * @param  hdac DAC handle
1401   * @param  CallbackID ID of the callback to be unregistered
1402   *         This parameter can be one of the following values:
1403   *          @arg @ref HAL_DAC_CH1_COMPLETE_CB_ID          DAC CH1 transfer Complete Callback ID
1404   *          @arg @ref HAL_DAC_CH1_HALF_COMPLETE_CB_ID     DAC CH1 Half Complete Callback ID
1405   *          @arg @ref HAL_DAC_CH1_ERROR_ID                DAC CH1 Error Callback ID
1406   *          @arg @ref HAL_DAC_CH1_UNDERRUN_CB_ID          DAC CH1 UnderRun Callback ID
1407   *          @arg @ref HAL_DAC_CH2_COMPLETE_CB_ID          DAC CH2 Complete Callback ID
1408   *          @arg @ref HAL_DAC_CH2_HALF_COMPLETE_CB_ID     DAC CH2 Half Complete Callback ID
1409   *          @arg @ref HAL_DAC_CH2_ERROR_ID                DAC CH2 Error Callback ID
1410   *          @arg @ref HAL_DAC_CH2_UNDERRUN_CB_ID          DAC CH2 UnderRun Callback ID
1411   *          @arg @ref HAL_DAC_MSPINIT_CB_ID               DAC MSP Init Callback ID
1412   *          @arg @ref HAL_DAC_MSPDEINIT_CB_ID             DAC MSP DeInit Callback ID
1413   *          @arg @ref HAL_DAC_ALL_CB_ID                   DAC All callbacks
1414   * @retval status
1415   */
1416 HAL_StatusTypeDef HAL_DAC_UnRegisterCallback(DAC_HandleTypeDef *hdac, HAL_DAC_CallbackIDTypeDef CallbackID)
1417 {
1418   HAL_StatusTypeDef status = HAL_OK;
1419 
1420   /* Check the DAC peripheral handle */
1421   if (hdac == NULL)
1422   {
1423     return HAL_ERROR;
1424   }
1425 
1426   if (hdac->State == HAL_DAC_STATE_READY)
1427   {
1428     switch (CallbackID)
1429     {
1430       case HAL_DAC_CH1_COMPLETE_CB_ID :
1431         hdac->ConvCpltCallbackCh1 = HAL_DAC_ConvCpltCallbackCh1;
1432         break;
1433       case HAL_DAC_CH1_HALF_COMPLETE_CB_ID :
1434         hdac->ConvHalfCpltCallbackCh1 = HAL_DAC_ConvHalfCpltCallbackCh1;
1435         break;
1436       case HAL_DAC_CH1_ERROR_ID :
1437         hdac->ErrorCallbackCh1 = HAL_DAC_ErrorCallbackCh1;
1438         break;
1439       case HAL_DAC_CH1_UNDERRUN_CB_ID :
1440         hdac->DMAUnderrunCallbackCh1 = HAL_DAC_DMAUnderrunCallbackCh1;
1441         break;
1442 
1443       case HAL_DAC_CH2_COMPLETE_CB_ID :
1444         hdac->ConvCpltCallbackCh2 = HAL_DACEx_ConvCpltCallbackCh2;
1445         break;
1446       case HAL_DAC_CH2_HALF_COMPLETE_CB_ID :
1447         hdac->ConvHalfCpltCallbackCh2 = HAL_DACEx_ConvHalfCpltCallbackCh2;
1448         break;
1449       case HAL_DAC_CH2_ERROR_ID :
1450         hdac->ErrorCallbackCh2 = HAL_DACEx_ErrorCallbackCh2;
1451         break;
1452       case HAL_DAC_CH2_UNDERRUN_CB_ID :
1453         hdac->DMAUnderrunCallbackCh2 = HAL_DACEx_DMAUnderrunCallbackCh2;
1454         break;
1455 
1456       case HAL_DAC_MSPINIT_CB_ID :
1457         hdac->MspInitCallback = HAL_DAC_MspInit;
1458         break;
1459       case HAL_DAC_MSPDEINIT_CB_ID :
1460         hdac->MspDeInitCallback = HAL_DAC_MspDeInit;
1461         break;
1462       case HAL_DAC_ALL_CB_ID :
1463         hdac->ConvCpltCallbackCh1 = HAL_DAC_ConvCpltCallbackCh1;
1464         hdac->ConvHalfCpltCallbackCh1 = HAL_DAC_ConvHalfCpltCallbackCh1;
1465         hdac->ErrorCallbackCh1 = HAL_DAC_ErrorCallbackCh1;
1466         hdac->DMAUnderrunCallbackCh1 = HAL_DAC_DMAUnderrunCallbackCh1;
1467 
1468         hdac->ConvCpltCallbackCh2 = HAL_DACEx_ConvCpltCallbackCh2;
1469         hdac->ConvHalfCpltCallbackCh2 = HAL_DACEx_ConvHalfCpltCallbackCh2;
1470         hdac->ErrorCallbackCh2 = HAL_DACEx_ErrorCallbackCh2;
1471         hdac->DMAUnderrunCallbackCh2 = HAL_DACEx_DMAUnderrunCallbackCh2;
1472 
1473         hdac->MspInitCallback = HAL_DAC_MspInit;
1474         hdac->MspDeInitCallback = HAL_DAC_MspDeInit;
1475         break;
1476       default :
1477         /* Update the error code */
1478         hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK;
1479         /* update return status */
1480         status =  HAL_ERROR;
1481         break;
1482     }
1483   }
1484   else if (hdac->State == HAL_DAC_STATE_RESET)
1485   {
1486     switch (CallbackID)
1487     {
1488       case HAL_DAC_MSPINIT_CB_ID :
1489         hdac->MspInitCallback = HAL_DAC_MspInit;
1490         break;
1491       case HAL_DAC_MSPDEINIT_CB_ID :
1492         hdac->MspDeInitCallback = HAL_DAC_MspDeInit;
1493         break;
1494       default :
1495         /* Update the error code */
1496         hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK;
1497         /* update return status */
1498         status =  HAL_ERROR;
1499         break;
1500     }
1501   }
1502   else
1503   {
1504     /* Update the error code */
1505     hdac->ErrorCode |= HAL_DAC_ERROR_INVALID_CALLBACK;
1506     /* update return status */
1507     status =  HAL_ERROR;
1508   }
1509 
1510   return status;
1511 }
1512 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
1513 
1514 /**
1515   * @}
1516   */
1517 
1518 /**
1519   * @}
1520   */
1521 
1522 /** @addtogroup DAC_Private_Functions
1523   * @{
1524   */
1525 
1526 /**
1527   * @brief  DMA conversion complete callback.
1528   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1529   *                the configuration information for the specified DMA module.
1530   * @retval None
1531   */
1532 void DAC_DMAConvCpltCh1(DMA_HandleTypeDef *hdma)
1533 {
1534   DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1535 
1536 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
1537   hdac->ConvCpltCallbackCh1(hdac);
1538 #else
1539   HAL_DAC_ConvCpltCallbackCh1(hdac);
1540 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
1541 
1542   hdac->State = HAL_DAC_STATE_READY;
1543 }
1544 
1545 /**
1546   * @brief  DMA half transfer complete callback.
1547   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1548   *                the configuration information for the specified DMA module.
1549   * @retval None
1550   */
1551 void DAC_DMAHalfConvCpltCh1(DMA_HandleTypeDef *hdma)
1552 {
1553   DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1554   /* Conversion complete callback */
1555 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
1556   hdac->ConvHalfCpltCallbackCh1(hdac);
1557 #else
1558   HAL_DAC_ConvHalfCpltCallbackCh1(hdac);
1559 #endif  /* USE_HAL_DAC_REGISTER_CALLBACKS */
1560 }
1561 
1562 /**
1563   * @brief  DMA error callback
1564   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1565   *                the configuration information for the specified DMA module.
1566   * @retval None
1567   */
1568 void DAC_DMAErrorCh1(DMA_HandleTypeDef *hdma)
1569 {
1570   DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1571 
1572   /* Set DAC error code to DMA error */
1573   hdac->ErrorCode |= HAL_DAC_ERROR_DMA;
1574 
1575 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
1576   hdac->ErrorCallbackCh1(hdac);
1577 #else
1578   HAL_DAC_ErrorCallbackCh1(hdac);
1579 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
1580 
1581   hdac->State = HAL_DAC_STATE_READY;
1582 }
1583 
1584 /**
1585   * @}
1586   */
1587 
1588 /**
1589   * @}
1590   */
1591 
1592 #endif /* DAC1 || DAC2 */
1593 
1594 #endif /* HAL_DAC_MODULE_ENABLED */
1595 /**
1596   * @}
1597   */