Back to home page

LXR

 
 

    


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

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_dac_ex.c
0004   * @author  MCD Application Team
0005   * @brief   Extended DAC HAL module driver.
0006   *          This file provides firmware functions to manage the extended
0007   *          functionalities of the DAC peripheral.
0008   *
0009   *
0010   ******************************************************************************
0011   * @attention
0012   *
0013   * Copyright (c) 2017 STMicroelectronics.
0014   * All rights reserved.
0015   *
0016   * This software is licensed under terms that can be found in the LICENSE file
0017   * in the root directory of this software component.
0018   * If no LICENSE file comes with this software, it is provided AS-IS.
0019   *
0020   ******************************************************************************
0021   @verbatim
0022   ==============================================================================
0023                       ##### How to use this driver #####
0024   ==============================================================================
0025     [..]
0026      *** Dual mode IO operation ***
0027      ==============================
0028      [..]
0029       (+) Use HAL_DACEx_DualStart() to enable both channel and start conversion
0030           for dual mode operation.
0031           If software trigger is selected, using HAL_DACEx_DualStart() will start
0032           the conversion of the value previously set by HAL_DACEx_DualSetValue().
0033       (+) Use HAL_DACEx_DualStop() to disable both channel and stop conversion
0034           for dual mode operation.
0035       (+) Use HAL_DACEx_DualStart_DMA() to enable both channel and start conversion
0036           for dual mode operation using DMA to feed DAC converters.
0037           First issued trigger will start the conversion of the value previously
0038           set by HAL_DACEx_DualSetValue().
0039           The same callbacks that are used in single mode are called in dual mode to notify
0040           transfer completion (half complete or complete), errors or underrun.
0041       (+) Use HAL_DACEx_DualStop_DMA() to disable both channel and stop conversion
0042           for dual mode operation using DMA to feed DAC converters.
0043       (+) When Dual mode is enabled (i.e. DAC Channel1 and Channel2 are used simultaneously) :
0044           Use HAL_DACEx_DualGetValue() to get digital data to be converted and use
0045           HAL_DACEx_DualSetValue() to set digital value to converted simultaneously in
0046           Channel 1 and Channel 2.
0047      *** Signal generation operation ***
0048      ===================================
0049      [..]
0050       (+) Use HAL_DACEx_TriangleWaveGenerate() to generate Triangle signal.
0051       (+) Use HAL_DACEx_NoiseWaveGenerate() to generate Noise signal.
0052 
0053       (+) HAL_DACEx_SelfCalibrate to calibrate one DAC channel.
0054       (+) HAL_DACEx_SetUserTrimming to set user trimming value.
0055       (+) HAL_DACEx_GetTrimOffset to retrieve trimming value (factory setting
0056           after reset, user setting if HAL_DACEx_SetUserTrimming have been used
0057           at least one time after reset).
0058 
0059  @endverbatim
0060   ******************************************************************************
0061   */
0062 
0063 
0064 /* Includes ------------------------------------------------------------------*/
0065 #include "stm32h7xx_hal.h"
0066 
0067 /** @addtogroup STM32H7xx_HAL_Driver
0068   * @{
0069   */
0070 
0071 #ifdef HAL_DAC_MODULE_ENABLED
0072 
0073 #if defined(DAC1) || defined(DAC2)
0074 
0075 /** @defgroup DACEx DACEx
0076   * @ingroup RTEMSBSPsARMSTM32H7
0077   * @brief DAC Extended HAL module driver
0078   * @{
0079   */
0080 
0081 /* Private typedef -----------------------------------------------------------*/
0082 /* Private define ------------------------------------------------------------*/
0083 
0084 /* Delay for DAC minimum trimming time.                                       */
0085 /* Note: minimum time needed between two calibration steps                    */
0086 /*       The delay below is specified under conditions:                       */
0087 /*        - DAC channel output buffer enabled                                 */
0088 /* Literal set to maximum value (refer to device datasheet,                   */
0089 /* electrical characteristics, parameter "tTRIM").                            */
0090 /* Unit: us                                                                   */
0091 #define DAC_DELAY_TRIM_US          (50UL)     /*!< Delay for DAC minimum trimming time */
0092 
0093 /* Private macro -------------------------------------------------------------*/
0094 /* Private variables ---------------------------------------------------------*/
0095 /* Private function prototypes -----------------------------------------------*/
0096 /* Exported functions --------------------------------------------------------*/
0097 
0098 /** @defgroup DACEx_Exported_Functions DACEx Exported Functions
0099   * @ingroup RTEMSBSPsARMSTM32H7
0100   * @{
0101   */
0102 
0103 /** @defgroup DACEx_Exported_Functions_Group2 IO operation functions
0104   * @ingroup RTEMSBSPsARMSTM32H7
0105   *  @brief    Extended IO operation functions
0106   *
0107 @verbatim
0108   ==============================================================================
0109                  ##### Extended features functions #####
0110   ==============================================================================
0111     [..]  This section provides functions allowing to:
0112       (+) Start conversion.
0113       (+) Stop conversion.
0114       (+) Start conversion and enable DMA transfer.
0115       (+) Stop conversion and disable DMA transfer.
0116       (+) Get result of conversion.
0117       (+) Get result of dual mode conversion.
0118 
0119 @endverbatim
0120   * @{
0121   */
0122 
0123 
0124 /**
0125   * @brief  Enables DAC and starts conversion of both channels.
0126   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0127   *         the configuration information for the specified DAC.
0128   * @retval HAL status
0129   */
0130 HAL_StatusTypeDef HAL_DACEx_DualStart(DAC_HandleTypeDef *hdac)
0131 {
0132   uint32_t tmp_swtrig = 0UL;
0133 
0134   /* Check the DAC peripheral handle */
0135   if (hdac == NULL)
0136   {
0137     return HAL_ERROR;
0138   }
0139 
0140 
0141   /* Process locked */
0142   __HAL_LOCK(hdac);
0143 
0144   /* Change DAC state */
0145   hdac->State = HAL_DAC_STATE_BUSY;
0146 
0147   /* Enable the Peripheral */
0148   __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_1);
0149   __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_2);
0150 
0151   /* Check if software trigger enabled */
0152   if ((hdac->Instance->CR & (DAC_CR_TEN1 | DAC_CR_TSEL1)) == DAC_TRIGGER_SOFTWARE)
0153   {
0154     tmp_swtrig |= DAC_SWTRIGR_SWTRIG1;
0155   }
0156   if ((hdac->Instance->CR & (DAC_CR_TEN2 | DAC_CR_TSEL2)) == (DAC_TRIGGER_SOFTWARE << (DAC_CHANNEL_2 & 0x10UL)))
0157   {
0158     tmp_swtrig |= DAC_SWTRIGR_SWTRIG2;
0159   }
0160   /* Enable the selected DAC software conversion*/
0161   SET_BIT(hdac->Instance->SWTRIGR, tmp_swtrig);
0162 
0163   /* Change DAC state */
0164   hdac->State = HAL_DAC_STATE_READY;
0165 
0166   /* Process unlocked */
0167   __HAL_UNLOCK(hdac);
0168 
0169   /* Return function status */
0170   return HAL_OK;
0171 }
0172 
0173 /**
0174   * @brief  Disables DAC and stop conversion of both channels.
0175   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0176   *         the configuration information for the specified DAC.
0177   * @retval HAL status
0178   */
0179 HAL_StatusTypeDef HAL_DACEx_DualStop(DAC_HandleTypeDef *hdac)
0180 {
0181   /* Check the DAC peripheral handle */
0182   if (hdac == NULL)
0183   {
0184     return HAL_ERROR;
0185   }
0186 
0187 
0188   /* Disable the Peripheral */
0189   __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_1);
0190   __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_2);
0191 
0192   /* Change DAC state */
0193   hdac->State = HAL_DAC_STATE_READY;
0194 
0195   /* Return function status */
0196   return HAL_OK;
0197 }
0198 
0199 /**
0200   * @brief  Enables DAC and starts conversion of both channel 1 and 2 of the same DAC.
0201   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0202   *         the configuration information for the specified DAC.
0203   * @param  Channel The DAC channel that will request data from DMA.
0204   *          This parameter can be one of the following values:
0205   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
0206   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
0207   * @param  pData The destination peripheral Buffer address.
0208   * @param  Length The length of data to be transferred from memory to DAC peripheral
0209   * @param  Alignment Specifies the data alignment for DAC channel.
0210   *          This parameter can be one of the following values:
0211   *            @arg DAC_ALIGN_8B_R: 8bit right data alignment selected
0212   *            @arg DAC_ALIGN_12B_L: 12bit left data alignment selected
0213   *            @arg DAC_ALIGN_12B_R: 12bit right data alignment selected
0214   * @retval HAL status
0215   */
0216 HAL_StatusTypeDef HAL_DACEx_DualStart_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel,
0217                                           const uint32_t *pData, uint32_t Length, uint32_t Alignment)
0218 {
0219   HAL_StatusTypeDef status;
0220   uint32_t tmpreg = 0UL;
0221 
0222   /* Check the DAC peripheral handle */
0223   if (hdac == NULL)
0224   {
0225     return HAL_ERROR;
0226   }
0227 
0228   /* Check the parameters */
0229   assert_param(IS_DAC_CHANNEL(Channel));
0230   assert_param(IS_DAC_ALIGN(Alignment));
0231 
0232   /* Process locked */
0233   __HAL_LOCK(hdac);
0234 
0235   /* Change DAC state */
0236   hdac->State = HAL_DAC_STATE_BUSY;
0237 
0238   if (Channel == DAC_CHANNEL_1)
0239   {
0240     /* Set the DMA transfer complete callback for channel1 */
0241     hdac->DMA_Handle1->XferCpltCallback = DAC_DMAConvCpltCh1;
0242 
0243     /* Set the DMA half transfer complete callback for channel1 */
0244     hdac->DMA_Handle1->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh1;
0245 
0246     /* Set the DMA error callback for channel1 */
0247     hdac->DMA_Handle1->XferErrorCallback = DAC_DMAErrorCh1;
0248 
0249     /* Enable the selected DAC channel1 DMA request */
0250     SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN1);
0251   }
0252   else
0253   {
0254     /* Set the DMA transfer complete callback for channel2 */
0255     hdac->DMA_Handle2->XferCpltCallback = DAC_DMAConvCpltCh2;
0256 
0257     /* Set the DMA half transfer complete callback for channel2 */
0258     hdac->DMA_Handle2->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh2;
0259 
0260     /* Set the DMA error callback for channel2 */
0261     hdac->DMA_Handle2->XferErrorCallback = DAC_DMAErrorCh2;
0262 
0263     /* Enable the selected DAC channel2 DMA request */
0264     SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN2);
0265   }
0266 
0267   switch (Alignment)
0268   {
0269     case DAC_ALIGN_12B_R:
0270       /* Get DHR12R1 address */
0271       tmpreg = (uint32_t)&hdac->Instance->DHR12RD;
0272       break;
0273     case DAC_ALIGN_12B_L:
0274       /* Get DHR12L1 address */
0275       tmpreg = (uint32_t)&hdac->Instance->DHR12LD;
0276       break;
0277     case DAC_ALIGN_8B_R:
0278       /* Get DHR8R1 address */
0279       tmpreg = (uint32_t)&hdac->Instance->DHR8RD;
0280       break;
0281     default:
0282       break;
0283   }
0284 
0285   /* Enable the DMA channel */
0286   if (Channel == DAC_CHANNEL_1)
0287   {
0288     /* Enable the DAC DMA underrun interrupt */
0289     __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR1);
0290 
0291     /* Enable the DMA channel */
0292     status = HAL_DMA_Start_IT(hdac->DMA_Handle1, (uint32_t)pData, tmpreg, Length);
0293   }
0294   else
0295   {
0296     /* Enable the DAC DMA underrun interrupt */
0297     __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR2);
0298 
0299     /* Enable the DMA channel */
0300     status = HAL_DMA_Start_IT(hdac->DMA_Handle2, (uint32_t)pData, tmpreg, Length);
0301   }
0302 
0303   /* Process Unlocked */
0304   __HAL_UNLOCK(hdac);
0305 
0306   if (status == HAL_OK)
0307   {
0308     /* Enable the Peripheral */
0309     __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_1);
0310     __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_2);
0311   }
0312   else
0313   {
0314     hdac->ErrorCode |= HAL_DAC_ERROR_DMA;
0315   }
0316 
0317   /* Return function status */
0318   return status;
0319 }
0320 
0321 /**
0322   * @brief  Disables DAC and stop conversion both channel.
0323   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0324   *         the configuration information for the specified DAC.
0325   * @param  Channel The DAC channel that requests data from DMA.
0326   *          This parameter can be one of the following values:
0327   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
0328   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
0329   * @retval HAL status
0330   */
0331 HAL_StatusTypeDef HAL_DACEx_DualStop_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel)
0332 {
0333   HAL_StatusTypeDef status;
0334 
0335   /* Check the DAC peripheral handle */
0336   if (hdac == NULL)
0337   {
0338     return HAL_ERROR;
0339   }
0340 
0341 
0342   /* Disable the selected DAC channel DMA request */
0343   CLEAR_BIT(hdac->Instance->CR, DAC_CR_DMAEN2 | DAC_CR_DMAEN1);
0344 
0345   /* Disable the Peripheral */
0346   __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_1);
0347   __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_2);
0348 
0349   /* Disable the DMA channel */
0350 
0351   /* Channel1 is used */
0352   if (Channel == DAC_CHANNEL_1)
0353   {
0354     /* Disable the DMA channel */
0355     status = HAL_DMA_Abort(hdac->DMA_Handle1);
0356 
0357     /* Disable the DAC DMA underrun interrupt */
0358     __HAL_DAC_DISABLE_IT(hdac, DAC_IT_DMAUDR1);
0359   }
0360   else
0361   {
0362     /* Disable the DMA channel */
0363     status = HAL_DMA_Abort(hdac->DMA_Handle2);
0364 
0365     /* Disable the DAC DMA underrun interrupt */
0366     __HAL_DAC_DISABLE_IT(hdac, DAC_IT_DMAUDR2);
0367   }
0368 
0369   /* Check if DMA Channel effectively disabled */
0370   if (status != HAL_OK)
0371   {
0372     /* Update DAC state machine to error */
0373     hdac->State = HAL_DAC_STATE_ERROR;
0374   }
0375   else
0376   {
0377     /* Change DAC state */
0378     hdac->State = HAL_DAC_STATE_READY;
0379   }
0380 
0381   /* Return function status */
0382   return status;
0383 }
0384 
0385 
0386 /**
0387   * @brief  Enable or disable the selected DAC channel wave generation.
0388   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0389   *         the configuration information for the specified DAC.
0390   * @param  Channel The selected DAC channel.
0391   *          This parameter can be one of the following values:
0392   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
0393   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
0394   * @param  Amplitude Select max triangle amplitude.
0395   *          This parameter can be one of the following values:
0396   *            @arg DAC_TRIANGLEAMPLITUDE_1: Select max triangle amplitude of 1
0397   *            @arg DAC_TRIANGLEAMPLITUDE_3: Select max triangle amplitude of 3
0398   *            @arg DAC_TRIANGLEAMPLITUDE_7: Select max triangle amplitude of 7
0399   *            @arg DAC_TRIANGLEAMPLITUDE_15: Select max triangle amplitude of 15
0400   *            @arg DAC_TRIANGLEAMPLITUDE_31: Select max triangle amplitude of 31
0401   *            @arg DAC_TRIANGLEAMPLITUDE_63: Select max triangle amplitude of 63
0402   *            @arg DAC_TRIANGLEAMPLITUDE_127: Select max triangle amplitude of 127
0403   *            @arg DAC_TRIANGLEAMPLITUDE_255: Select max triangle amplitude of 255
0404   *            @arg DAC_TRIANGLEAMPLITUDE_511: Select max triangle amplitude of 511
0405   *            @arg DAC_TRIANGLEAMPLITUDE_1023: Select max triangle amplitude of 1023
0406   *            @arg DAC_TRIANGLEAMPLITUDE_2047: Select max triangle amplitude of 2047
0407   *            @arg DAC_TRIANGLEAMPLITUDE_4095: Select max triangle amplitude of 4095
0408   * @retval HAL status
0409   */
0410 HAL_StatusTypeDef HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Amplitude)
0411 {
0412   /* Check the DAC peripheral handle */
0413   if (hdac == NULL)
0414   {
0415     return HAL_ERROR;
0416   }
0417 
0418   /* Check the parameters */
0419   assert_param(IS_DAC_CHANNEL(Channel));
0420   assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude));
0421 
0422   /* Process locked */
0423   __HAL_LOCK(hdac);
0424 
0425   /* Change DAC state */
0426   hdac->State = HAL_DAC_STATE_BUSY;
0427 
0428   /* Enable the triangle wave generation for the selected DAC channel */
0429   MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1) | (DAC_CR_MAMP1)) << (Channel & 0x10UL),
0430              (DAC_CR_WAVE1_1 | Amplitude) << (Channel & 0x10UL));
0431 
0432   /* Change DAC state */
0433   hdac->State = HAL_DAC_STATE_READY;
0434 
0435   /* Process unlocked */
0436   __HAL_UNLOCK(hdac);
0437 
0438   /* Return function status */
0439   return HAL_OK;
0440 }
0441 
0442 /**
0443   * @brief  Enable or disable the selected DAC channel wave generation.
0444   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0445   *         the configuration information for the specified DAC.
0446   * @param  Channel The selected DAC channel.
0447   *          This parameter can be one of the following values:
0448   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
0449   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
0450   * @param  Amplitude Unmask DAC channel LFSR for noise wave generation.
0451   *          This parameter can be one of the following values:
0452   *            @arg DAC_LFSRUNMASK_BIT0: Unmask DAC channel LFSR bit0 for noise wave generation
0453   *            @arg DAC_LFSRUNMASK_BITS1_0: Unmask DAC channel LFSR bit[1:0] for noise wave generation
0454   *            @arg DAC_LFSRUNMASK_BITS2_0: Unmask DAC channel LFSR bit[2:0] for noise wave generation
0455   *            @arg DAC_LFSRUNMASK_BITS3_0: Unmask DAC channel LFSR bit[3:0] for noise wave generation
0456   *            @arg DAC_LFSRUNMASK_BITS4_0: Unmask DAC channel LFSR bit[4:0] for noise wave generation
0457   *            @arg DAC_LFSRUNMASK_BITS5_0: Unmask DAC channel LFSR bit[5:0] for noise wave generation
0458   *            @arg DAC_LFSRUNMASK_BITS6_0: Unmask DAC channel LFSR bit[6:0] for noise wave generation
0459   *            @arg DAC_LFSRUNMASK_BITS7_0: Unmask DAC channel LFSR bit[7:0] for noise wave generation
0460   *            @arg DAC_LFSRUNMASK_BITS8_0: Unmask DAC channel LFSR bit[8:0] for noise wave generation
0461   *            @arg DAC_LFSRUNMASK_BITS9_0: Unmask DAC channel LFSR bit[9:0] for noise wave generation
0462   *            @arg DAC_LFSRUNMASK_BITS10_0: Unmask DAC channel LFSR bit[10:0] for noise wave generation
0463   *            @arg DAC_LFSRUNMASK_BITS11_0: Unmask DAC channel LFSR bit[11:0] for noise wave generation
0464   * @retval HAL status
0465   */
0466 HAL_StatusTypeDef HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Amplitude)
0467 {
0468   /* Check the DAC peripheral handle */
0469   if (hdac == NULL)
0470   {
0471     return HAL_ERROR;
0472   }
0473 
0474   /* Check the parameters */
0475   assert_param(IS_DAC_CHANNEL(Channel));
0476   assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude));
0477 
0478   /* Process locked */
0479   __HAL_LOCK(hdac);
0480 
0481   /* Change DAC state */
0482   hdac->State = HAL_DAC_STATE_BUSY;
0483 
0484   /* Enable the noise wave generation for the selected DAC channel */
0485   MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1) | (DAC_CR_MAMP1)) << (Channel & 0x10UL),
0486              (DAC_CR_WAVE1_0 | Amplitude) << (Channel & 0x10UL));
0487 
0488   /* Change DAC state */
0489   hdac->State = HAL_DAC_STATE_READY;
0490 
0491   /* Process unlocked */
0492   __HAL_UNLOCK(hdac);
0493 
0494   /* Return function status */
0495   return HAL_OK;
0496 }
0497 
0498 
0499 /**
0500   * @brief  Set the specified data holding register value for dual DAC channel.
0501   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0502   *               the configuration information for the specified DAC.
0503   * @param  Alignment Specifies the data alignment for dual channel DAC.
0504   *          This parameter can be one of the following values:
0505   *            DAC_ALIGN_8B_R: 8bit right data alignment selected
0506   *            DAC_ALIGN_12B_L: 12bit left data alignment selected
0507   *            DAC_ALIGN_12B_R: 12bit right data alignment selected
0508   * @param  Data1 Data for DAC Channel1 to be loaded in the selected data holding register.
0509   * @param  Data2 Data for DAC Channel2 to be loaded in the selected data  holding register.
0510   * @note   In dual mode, a unique register access is required to write in both
0511   *          DAC channels at the same time.
0512   * @retval HAL status
0513   */
0514 HAL_StatusTypeDef HAL_DACEx_DualSetValue(DAC_HandleTypeDef *hdac, uint32_t Alignment, uint32_t Data1, uint32_t Data2)
0515 {
0516   uint32_t data;
0517   uint32_t tmp;
0518 
0519   /* Check the DAC peripheral handle */
0520   if (hdac == NULL)
0521   {
0522     return HAL_ERROR;
0523   }
0524 
0525   /* Check the parameters */
0526   assert_param(IS_DAC_ALIGN(Alignment));
0527   assert_param(IS_DAC_DATA(Data1));
0528   assert_param(IS_DAC_DATA(Data2));
0529 
0530   /* Calculate and set dual DAC data holding register value */
0531   if (Alignment == DAC_ALIGN_8B_R)
0532   {
0533     data = ((uint32_t)Data2 << 8U) | Data1;
0534   }
0535   else
0536   {
0537     data = ((uint32_t)Data2 << 16U) | Data1;
0538   }
0539 
0540   tmp = (uint32_t)hdac->Instance;
0541   tmp += DAC_DHR12RD_ALIGNMENT(Alignment);
0542 
0543   /* Set the dual DAC selected data holding register */
0544   *(__IO uint32_t *)tmp = data;
0545 
0546   /* Return function status */
0547   return HAL_OK;
0548 }
0549 
0550 /**
0551   * @brief  Conversion complete callback in non-blocking mode for Channel2.
0552   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0553   *         the configuration information for the specified DAC.
0554   * @retval None
0555   */
0556 __weak void HAL_DACEx_ConvCpltCallbackCh2(DAC_HandleTypeDef *hdac)
0557 {
0558   /* Prevent unused argument(s) compilation warning */
0559   UNUSED(hdac);
0560 
0561   /* NOTE : This function should not be modified, when the callback is needed,
0562             the HAL_DACEx_ConvCpltCallbackCh2 could be implemented in the user file
0563    */
0564 }
0565 
0566 /**
0567   * @brief  Conversion half DMA transfer callback in non-blocking mode for Channel2.
0568   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0569   *         the configuration information for the specified DAC.
0570   * @retval None
0571   */
0572 __weak void HAL_DACEx_ConvHalfCpltCallbackCh2(DAC_HandleTypeDef *hdac)
0573 {
0574   /* Prevent unused argument(s) compilation warning */
0575   UNUSED(hdac);
0576 
0577   /* NOTE : This function should not be modified, when the callback is needed,
0578             the HAL_DACEx_ConvHalfCpltCallbackCh2 could be implemented in the user file
0579    */
0580 }
0581 
0582 /**
0583   * @brief  Error DAC callback for Channel2.
0584   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0585   *         the configuration information for the specified DAC.
0586   * @retval None
0587   */
0588 __weak void HAL_DACEx_ErrorCallbackCh2(DAC_HandleTypeDef *hdac)
0589 {
0590   /* Prevent unused argument(s) compilation warning */
0591   UNUSED(hdac);
0592 
0593   /* NOTE : This function should not be modified, when the callback is needed,
0594             the HAL_DACEx_ErrorCallbackCh2 could be implemented in the user file
0595    */
0596 }
0597 
0598 /**
0599   * @brief  DMA underrun DAC callback for Channel2.
0600   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0601   *         the configuration information for the specified DAC.
0602   * @retval None
0603   */
0604 __weak void HAL_DACEx_DMAUnderrunCallbackCh2(DAC_HandleTypeDef *hdac)
0605 {
0606   /* Prevent unused argument(s) compilation warning */
0607   UNUSED(hdac);
0608 
0609   /* NOTE : This function should not be modified, when the callback is needed,
0610             the HAL_DACEx_DMAUnderrunCallbackCh2 could be implemented in the user file
0611    */
0612 }
0613 
0614 
0615 /**
0616   * @brief  Run the self calibration of one DAC channel.
0617   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0618   *         the configuration information for the specified DAC.
0619   * @param  sConfig DAC channel configuration structure.
0620   * @param  Channel The selected DAC channel.
0621   *          This parameter can be one of the following values:
0622   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
0623   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
0624   * @retval Updates DAC_TrimmingValue. , DAC_UserTrimming set to DAC_UserTrimming
0625   * @retval HAL status
0626   * @note   Calibration runs about 7 ms.
0627   */
0628 HAL_StatusTypeDef HAL_DACEx_SelfCalibrate(DAC_HandleTypeDef *hdac, DAC_ChannelConfTypeDef *sConfig, uint32_t Channel)
0629 {
0630   HAL_StatusTypeDef status = HAL_OK;
0631 
0632   uint32_t trimmingvalue;
0633   uint32_t delta;
0634   __IO uint32_t wait_loop_index;
0635 
0636   /* store/restore channel configuration structure purpose */
0637   uint32_t oldmodeconfiguration;
0638 
0639   /* Check the parameters */
0640   assert_param(IS_DAC_CHANNEL(Channel));
0641 
0642   /* Check the DAC handle allocation */
0643   /* Check if DAC running */
0644   if ((hdac == NULL) || (sConfig == NULL))
0645   {
0646     status = HAL_ERROR;
0647   }
0648   else if (hdac->State == HAL_DAC_STATE_BUSY)
0649   {
0650     status = HAL_ERROR;
0651   }
0652   else
0653   {
0654     /* Process locked */
0655     __HAL_LOCK(hdac);
0656 
0657     /* Store configuration */
0658     oldmodeconfiguration = (hdac->Instance->MCR & (DAC_MCR_MODE1 << (Channel & 0x10UL)));
0659 
0660     /* Disable the selected DAC channel */
0661     CLEAR_BIT((hdac->Instance->CR), (DAC_CR_EN1 << (Channel & 0x10UL)));
0662 
0663     /* Set mode in MCR  for calibration */
0664     MODIFY_REG(hdac->Instance->MCR, (DAC_MCR_MODE1 << (Channel & 0x10UL)), 0U);
0665 
0666     /* Enable the selected DAC channel calibration */
0667     /* i.e. set DAC_CR_CENx bit */
0668     SET_BIT((hdac->Instance->CR), (DAC_CR_CEN1 << (Channel & 0x10UL)));
0669 
0670     /* Init trimming counter */
0671     /* Medium value */
0672     trimmingvalue = 16UL;
0673     delta = 8UL;
0674     while (delta != 0UL)
0675     {
0676       /* Set candidate trimming */
0677       MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (trimmingvalue << (Channel & 0x10UL)));
0678 
0679       /* Wait minimum time needed between two calibration steps (OTRIM) */
0680       /* Wait loop initialization and execution */
0681       /* Note: Variable divided by 2 to compensate partially CPU processing cycles, scaling in us split to not exceed */
0682       /*       32 bits register capacity and handle low frequency. */
0683       wait_loop_index = ((DAC_DELAY_TRIM_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
0684       while (wait_loop_index != 0UL)
0685       {
0686         wait_loop_index--;
0687       }
0688 
0689       if ((hdac->Instance->SR & (DAC_SR_CAL_FLAG1 << (Channel & 0x10UL))) == (DAC_SR_CAL_FLAG1 << (Channel & 0x10UL)))
0690       {
0691         /* DAC_SR_CAL_FLAGx is HIGH try higher trimming */
0692         trimmingvalue -= delta;
0693       }
0694       else
0695       {
0696         /* DAC_SR_CAL_FLAGx is LOW try lower trimming */
0697         trimmingvalue += delta;
0698       }
0699       delta >>= 1UL;
0700     }
0701 
0702     /* Still need to check if right calibration is current value or one step below */
0703     /* Indeed the first value that causes the DAC_SR_CAL_FLAGx bit to change from 0 to 1  */
0704     /* Set candidate trimming */
0705     MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (trimmingvalue << (Channel & 0x10UL)));
0706 
0707     /* Wait minimum time needed between two calibration steps (OTRIM) */
0708     /* Wait loop initialization and execution */
0709     /* Note: Variable divided by 2 to compensate partially CPU processing cycles, scaling in us split to not exceed */
0710     /*       32 bits register capacity and handle low frequency. */
0711     wait_loop_index = ((DAC_DELAY_TRIM_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
0712     while (wait_loop_index != 0UL)
0713     {
0714       wait_loop_index--;
0715     }
0716 
0717     if ((hdac->Instance->SR & (DAC_SR_CAL_FLAG1 << (Channel & 0x10UL))) == 0UL)
0718     {
0719       /* Trimming is actually one value more */
0720       trimmingvalue++;
0721       /* Set right trimming */
0722       MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (trimmingvalue << (Channel & 0x10UL)));
0723     }
0724 
0725     /* Disable the selected DAC channel calibration */
0726     /* i.e. clear DAC_CR_CENx bit */
0727     CLEAR_BIT((hdac->Instance->CR), (DAC_CR_CEN1 << (Channel & 0x10UL)));
0728 
0729     sConfig->DAC_TrimmingValue = trimmingvalue;
0730     sConfig->DAC_UserTrimming = DAC_TRIMMING_USER;
0731 
0732     /* Restore configuration */
0733     MODIFY_REG(hdac->Instance->MCR, (DAC_MCR_MODE1 << (Channel & 0x10UL)), oldmodeconfiguration);
0734 
0735     /* Process unlocked */
0736     __HAL_UNLOCK(hdac);
0737   }
0738 
0739   return status;
0740 }
0741 
0742 /**
0743   * @brief  Set the trimming mode and trimming value (user trimming mode applied).
0744   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0745   *         the configuration information for the specified DAC.
0746   * @param  sConfig DAC configuration structure updated with new DAC trimming value.
0747   * @param  Channel The selected DAC channel.
0748   *          This parameter can be one of the following values:
0749   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
0750   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
0751   * @param  NewTrimmingValue DAC new trimming value
0752   * @retval HAL status
0753   */
0754 HAL_StatusTypeDef HAL_DACEx_SetUserTrimming(DAC_HandleTypeDef *hdac, DAC_ChannelConfTypeDef *sConfig, uint32_t Channel,
0755                                             uint32_t NewTrimmingValue)
0756 {
0757   HAL_StatusTypeDef status = HAL_OK;
0758 
0759   /* Check the parameters */
0760   assert_param(IS_DAC_CHANNEL(Channel));
0761   assert_param(IS_DAC_NEWTRIMMINGVALUE(NewTrimmingValue));
0762 
0763   /* Check the DAC handle and channel configuration struct allocation */
0764   if ((hdac == NULL) || (sConfig == NULL))
0765   {
0766     status = HAL_ERROR;
0767   }
0768   else
0769   {
0770     /* Process locked */
0771     __HAL_LOCK(hdac);
0772 
0773     /* Set new trimming */
0774     MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (NewTrimmingValue << (Channel & 0x10UL)));
0775 
0776     /* Update trimming mode */
0777     sConfig->DAC_UserTrimming = DAC_TRIMMING_USER;
0778     sConfig->DAC_TrimmingValue = NewTrimmingValue;
0779 
0780     /* Process unlocked */
0781     __HAL_UNLOCK(hdac);
0782   }
0783   return status;
0784 }
0785 
0786 /**
0787   * @brief  Return the DAC trimming value.
0788   * @param  hdac DAC handle
0789   * @param  Channel The selected DAC channel.
0790   *          This parameter can be one of the following values:
0791   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
0792   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
0793   * @retval Trimming value : range: 0->31
0794   *
0795  */
0796 uint32_t HAL_DACEx_GetTrimOffset(const DAC_HandleTypeDef *hdac, uint32_t Channel)
0797 {
0798   /* Check the parameter */
0799   assert_param(IS_DAC_CHANNEL(Channel));
0800 
0801   /* Retrieve trimming */
0802   return ((hdac->Instance->CCR & (DAC_CCR_OTRIM1 << (Channel & 0x10UL))) >> (Channel & 0x10UL));
0803 }
0804 
0805 /**
0806   * @}
0807   */
0808 
0809 /** @defgroup DACEx_Exported_Functions_Group3 Peripheral Control functions
0810   * @ingroup RTEMSBSPsARMSTM32H7
0811   *  @brief    Extended Peripheral Control functions
0812   *
0813 @verbatim
0814   ==============================================================================
0815              ##### Peripheral Control functions #####
0816   ==============================================================================
0817     [..]  This section provides functions allowing to:
0818       (+) Set the specified data holding register value for DAC channel.
0819 
0820 @endverbatim
0821   * @{
0822   */
0823 
0824 
0825 /**
0826   * @brief  Return the last data output value of the selected DAC channel.
0827   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
0828   *         the configuration information for the specified DAC.
0829   * @retval The selected DAC channel data output value.
0830   */
0831 uint32_t HAL_DACEx_DualGetValue(const DAC_HandleTypeDef *hdac)
0832 {
0833   uint32_t tmp = 0UL;
0834 
0835   tmp |= hdac->Instance->DOR1;
0836 
0837   tmp |= hdac->Instance->DOR2 << 16UL;
0838 
0839   /* Returns the DAC channel data output register value */
0840   return tmp;
0841 }
0842 
0843 
0844 /**
0845   * @}
0846   */
0847 /**
0848   * @}
0849   */
0850 
0851 /* Private functions ---------------------------------------------------------*/
0852 /** @defgroup DACEx_Private_Functions DACEx private functions
0853   * @ingroup RTEMSBSPsARMSTM32H7
0854   *  @brief    Extended private functions
0855   * @{
0856   */
0857 
0858 
0859 /**
0860   * @brief  DMA conversion complete callback.
0861   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
0862   *                the configuration information for the specified DMA module.
0863   * @retval None
0864   */
0865 void DAC_DMAConvCpltCh2(DMA_HandleTypeDef *hdma)
0866 {
0867   DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
0868 
0869 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
0870   hdac->ConvCpltCallbackCh2(hdac);
0871 #else
0872   HAL_DACEx_ConvCpltCallbackCh2(hdac);
0873 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
0874 
0875   hdac->State = HAL_DAC_STATE_READY;
0876 }
0877 
0878 /**
0879   * @brief  DMA half transfer complete callback.
0880   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
0881   *                the configuration information for the specified DMA module.
0882   * @retval None
0883   */
0884 void DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef *hdma)
0885 {
0886   DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
0887   /* Conversion complete callback */
0888 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
0889   hdac->ConvHalfCpltCallbackCh2(hdac);
0890 #else
0891   HAL_DACEx_ConvHalfCpltCallbackCh2(hdac);
0892 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
0893 }
0894 
0895 /**
0896   * @brief  DMA error callback.
0897   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
0898   *                the configuration information for the specified DMA module.
0899   * @retval None
0900   */
0901 void DAC_DMAErrorCh2(DMA_HandleTypeDef *hdma)
0902 {
0903   DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
0904 
0905   /* Set DAC error code to DMA error */
0906   hdac->ErrorCode |= HAL_DAC_ERROR_DMA;
0907 
0908 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
0909   hdac->ErrorCallbackCh2(hdac);
0910 #else
0911   HAL_DACEx_ErrorCallbackCh2(hdac);
0912 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
0913 
0914   hdac->State = HAL_DAC_STATE_READY;
0915 }
0916 
0917 
0918 /**
0919   * @}
0920   */
0921 
0922 /**
0923   * @}
0924   */
0925 
0926 #endif /* DAC1 || DAC2 */
0927 
0928 #endif /* HAL_DAC_MODULE_ENABLED */
0929 
0930 /**
0931   * @}
0932   */