STM32H735xx HAL User Manual
stm32h7xx_hal_dac_ex.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32h7xx_hal_dac_ex.c
00004   * @author  MCD Application Team
00005   * @brief   Extended DAC HAL module driver.
00006   *          This file provides firmware functions to manage the extended
00007   *          functionalities of the DAC peripheral.
00008   *
00009   *
00010   ******************************************************************************
00011   * @attention
00012   *
00013   * Copyright (c) 2017 STMicroelectronics.
00014   * All rights reserved.
00015   *
00016   * This software is licensed under terms that can be found in the LICENSE file
00017   * in the root directory of this software component.
00018   * If no LICENSE file comes with this software, it is provided AS-IS.
00019   *
00020   ******************************************************************************
00021   @verbatim
00022   ==============================================================================
00023                       ##### How to use this driver #####
00024   ==============================================================================
00025     [..]
00026 
00027      *** Dual mode IO operation ***
00028      ==============================
00029      [..]
00030       (+) Use HAL_DACEx_DualStart() to enable both channel and start conversion
00031           for dual mode operation.
00032           If software trigger is selected, using HAL_DACEx_DualStart() will start
00033           the conversion of the value previously set by HAL_DACEx_DualSetValue().
00034       (+) Use HAL_DACEx_DualStop() to disable both channel and stop conversion
00035           for dual mode operation.
00036       (+) Use HAL_DACEx_DualStart_DMA() to enable both channel and start conversion
00037           for dual mode operation using DMA to feed DAC converters.
00038           First issued trigger will start the conversion of the value previously
00039           set by HAL_DACEx_DualSetValue().
00040           The same callbacks that are used in single mode are called in dual mode to notify
00041           transfer completion (half complete or complete), errors or underrun.
00042       (+) Use HAL_DACEx_DualStop_DMA() to disable both channel and stop conversion
00043           for dual mode operation using DMA to feed DAC converters.
00044       (+) When Dual mode is enabled (i.e. DAC Channel1 and Channel2 are used simultaneously) :
00045           Use HAL_DACEx_DualGetValue() to get digital data to be converted and use
00046           HAL_DACEx_DualSetValue() to set digital value to converted simultaneously in
00047           Channel 1 and Channel 2.
00048 
00049      *** Signal generation operation ***
00050      ===================================
00051      [..]
00052       (+) Use HAL_DACEx_TriangleWaveGenerate() to generate Triangle signal.
00053       (+) Use HAL_DACEx_NoiseWaveGenerate() to generate Noise signal.
00054 
00055       (+) HAL_DACEx_SelfCalibrate to calibrate one DAC channel.
00056       (+) HAL_DACEx_SetUserTrimming to set user trimming value.
00057       (+) HAL_DACEx_GetTrimOffset to retrieve trimming value (factory setting
00058           after reset, user setting if HAL_DACEx_SetUserTrimming have been used
00059           at least one time after reset).
00060 
00061  @endverbatim
00062   ******************************************************************************
00063   */
00064 
00065 
00066 /* Includes ------------------------------------------------------------------*/
00067 #include "stm32h7xx_hal.h"
00068 
00069 /** @addtogroup STM32H7xx_HAL_Driver
00070   * @{
00071   */
00072 
00073 #ifdef HAL_DAC_MODULE_ENABLED
00074 
00075 #if defined(DAC1) || defined(DAC2)
00076 
00077 /** @defgroup DACEx DACEx
00078   * @brief DAC Extended HAL module driver
00079   * @{
00080   */
00081 
00082 /* Private typedef -----------------------------------------------------------*/
00083 /* Private define ------------------------------------------------------------*/
00084 /* Private macro -------------------------------------------------------------*/
00085 /* Private variables ---------------------------------------------------------*/
00086 /* Private function prototypes -----------------------------------------------*/
00087 /* Exported functions --------------------------------------------------------*/
00088 
00089 /** @defgroup DACEx_Exported_Functions DACEx Exported Functions
00090   * @{
00091   */
00092 
00093 /** @defgroup DACEx_Exported_Functions_Group2 IO operation functions
00094   *  @brief    Extended IO operation functions
00095   *
00096 @verbatim
00097   ==============================================================================
00098                  ##### Extended features functions #####
00099   ==============================================================================
00100     [..]  This section provides functions allowing to:
00101       (+) Start conversion.
00102       (+) Stop conversion.
00103       (+) Start conversion and enable DMA transfer.
00104       (+) Stop conversion and disable DMA transfer.
00105       (+) Get result of conversion.
00106       (+) Get result of dual mode conversion.
00107 
00108 @endverbatim
00109   * @{
00110   */
00111 
00112 
00113 /**
00114   * @brief  Enables DAC and starts conversion of both channels.
00115   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
00116   *         the configuration information for the specified DAC.
00117   * @retval HAL status
00118   */
00119 HAL_StatusTypeDef HAL_DACEx_DualStart(DAC_HandleTypeDef *hdac)
00120 {
00121   uint32_t tmp_swtrig = 0UL;
00122 
00123 
00124   /* Process locked */
00125   __HAL_LOCK(hdac);
00126 
00127   /* Change DAC state */
00128   hdac->State = HAL_DAC_STATE_BUSY;
00129 
00130   /* Enable the Peripheral */
00131   __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_1);
00132   __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_2);
00133 
00134   /* Check if software trigger enabled */
00135   if ((hdac->Instance->CR & (DAC_CR_TEN1 | DAC_CR_TSEL1)) == DAC_TRIGGER_SOFTWARE)
00136   {
00137     tmp_swtrig |= DAC_SWTRIGR_SWTRIG1;
00138   }
00139   if ((hdac->Instance->CR & (DAC_CR_TEN2 | DAC_CR_TSEL2)) == (DAC_TRIGGER_SOFTWARE << (DAC_CHANNEL_2 & 0x10UL)))
00140   {
00141     tmp_swtrig |= DAC_SWTRIGR_SWTRIG2;
00142   }
00143   /* Enable the selected DAC software conversion*/
00144   SET_BIT(hdac->Instance->SWTRIGR, tmp_swtrig);
00145 
00146   /* Change DAC state */
00147   hdac->State = HAL_DAC_STATE_READY;
00148 
00149   /* Process unlocked */
00150   __HAL_UNLOCK(hdac);
00151 
00152   /* Return function status */
00153   return HAL_OK;
00154 }
00155 
00156 /**
00157   * @brief  Disables DAC and stop conversion of both channels.
00158   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
00159   *         the configuration information for the specified DAC.
00160   * @retval HAL status
00161   */
00162 HAL_StatusTypeDef HAL_DACEx_DualStop(DAC_HandleTypeDef *hdac)
00163 {
00164 
00165   /* Disable the Peripheral */
00166   __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_1);
00167   __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_2);
00168 
00169   /* Change DAC state */
00170   hdac->State = HAL_DAC_STATE_READY;
00171 
00172   /* Return function status */
00173   return HAL_OK;
00174 }
00175 
00176 /**
00177   * @brief  Enables DAC and starts conversion of both channel 1 and 2 of the same DAC.
00178   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
00179   *         the configuration information for the specified DAC.
00180   * @param  Channel The DAC channel that will request data from DMA.
00181   *          This parameter can be one of the following values:
00182   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
00183   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
00184   * @param  pData The destination peripheral Buffer address.
00185   * @param  Length The length of data to be transferred from memory to DAC peripheral
00186   * @param  Alignment Specifies the data alignment for DAC channel.
00187   *          This parameter can be one of the following values:
00188   *            @arg DAC_ALIGN_8B_R: 8bit right data alignment selected
00189   *            @arg DAC_ALIGN_12B_L: 12bit left data alignment selected
00190   *            @arg DAC_ALIGN_12B_R: 12bit right data alignment selected
00191   * @retval HAL status
00192   */
00193 HAL_StatusTypeDef HAL_DACEx_DualStart_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t *pData, uint32_t Length,
00194                                           uint32_t Alignment)
00195 {
00196   HAL_StatusTypeDef status;
00197   uint32_t tmpreg = 0UL;
00198 
00199   /* Check the parameters */
00200   assert_param(IS_DAC_CHANNEL(Channel));
00201   assert_param(IS_DAC_ALIGN(Alignment));
00202 
00203   /* Process locked */
00204   __HAL_LOCK(hdac);
00205 
00206   /* Change DAC state */
00207   hdac->State = HAL_DAC_STATE_BUSY;
00208 
00209   if (Channel == DAC_CHANNEL_1)
00210   {
00211     /* Set the DMA transfer complete callback for channel1 */
00212     hdac->DMA_Handle1->XferCpltCallback = DAC_DMAConvCpltCh1;
00213 
00214     /* Set the DMA half transfer complete callback for channel1 */
00215     hdac->DMA_Handle1->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh1;
00216 
00217     /* Set the DMA error callback for channel1 */
00218     hdac->DMA_Handle1->XferErrorCallback = DAC_DMAErrorCh1;
00219 
00220     /* Enable the selected DAC channel1 DMA request */
00221     SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN1);
00222   }
00223   else
00224   {
00225     /* Set the DMA transfer complete callback for channel2 */
00226     hdac->DMA_Handle2->XferCpltCallback = DAC_DMAConvCpltCh2;
00227 
00228     /* Set the DMA half transfer complete callback for channel2 */
00229     hdac->DMA_Handle2->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh2;
00230 
00231     /* Set the DMA error callback for channel2 */
00232     hdac->DMA_Handle2->XferErrorCallback = DAC_DMAErrorCh2;
00233 
00234     /* Enable the selected DAC channel2 DMA request */
00235     SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN2);
00236   }
00237 
00238   switch (Alignment)
00239   {
00240     case DAC_ALIGN_12B_R:
00241       /* Get DHR12R1 address */
00242       tmpreg = (uint32_t)&hdac->Instance->DHR12RD;
00243       break;
00244     case DAC_ALIGN_12B_L:
00245       /* Get DHR12L1 address */
00246       tmpreg = (uint32_t)&hdac->Instance->DHR12LD;
00247       break;
00248     case DAC_ALIGN_8B_R:
00249       /* Get DHR8R1 address */
00250       tmpreg = (uint32_t)&hdac->Instance->DHR8RD;
00251       break;
00252     default:
00253       break;
00254   }
00255 
00256   /* Enable the DMA channel */
00257   if (Channel == DAC_CHANNEL_1)
00258   {
00259     /* Enable the DAC DMA underrun interrupt */
00260     __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR1);
00261 
00262     /* Enable the DMA channel */
00263     status = HAL_DMA_Start_IT(hdac->DMA_Handle1, (uint32_t)pData, tmpreg, Length);
00264   }
00265   else
00266   {
00267     /* Enable the DAC DMA underrun interrupt */
00268     __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR2);
00269 
00270     /* Enable the DMA channel */
00271     status = HAL_DMA_Start_IT(hdac->DMA_Handle2, (uint32_t)pData, tmpreg, Length);
00272   }
00273 
00274   /* Process Unlocked */
00275   __HAL_UNLOCK(hdac);
00276 
00277   if (status == HAL_OK)
00278   {
00279     /* Enable the Peripheral */
00280     __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_1);
00281     __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_2);
00282   }
00283   else
00284   {
00285     hdac->ErrorCode |= HAL_DAC_ERROR_DMA;
00286   }
00287 
00288   /* Return function status */
00289   return status;
00290 }
00291 
00292 /**
00293   * @brief  Disables DAC and stop conversion both channel.
00294   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
00295   *         the configuration information for the specified DAC.
00296   * @param  Channel The DAC channel that requests data from DMA.
00297   *          This parameter can be one of the following values:
00298   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
00299   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
00300   * @retval HAL status
00301   */
00302 HAL_StatusTypeDef HAL_DACEx_DualStop_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel)
00303 {
00304   HAL_StatusTypeDef status;
00305 
00306 
00307   /* Disable the selected DAC channel DMA request */
00308   CLEAR_BIT(hdac->Instance->CR, DAC_CR_DMAEN2 | DAC_CR_DMAEN1);
00309 
00310   /* Disable the Peripheral */
00311   __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_1);
00312   __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_2);
00313 
00314   /* Disable the DMA channel */
00315 
00316   /* Channel1 is used */
00317   if (Channel == DAC_CHANNEL_1)
00318   {
00319     /* Disable the DMA channel */
00320     status = HAL_DMA_Abort(hdac->DMA_Handle1);
00321 
00322     /* Disable the DAC DMA underrun interrupt */
00323     __HAL_DAC_DISABLE_IT(hdac, DAC_IT_DMAUDR1);
00324   }
00325   else
00326   {
00327     /* Disable the DMA channel */
00328     status = HAL_DMA_Abort(hdac->DMA_Handle2);
00329 
00330     /* Disable the DAC DMA underrun interrupt */
00331     __HAL_DAC_DISABLE_IT(hdac, DAC_IT_DMAUDR2);
00332   }
00333 
00334   /* Check if DMA Channel effectively disabled */
00335   if (status != HAL_OK)
00336   {
00337     /* Update DAC state machine to error */
00338     hdac->State = HAL_DAC_STATE_ERROR;
00339   }
00340   else
00341   {
00342     /* Change DAC state */
00343     hdac->State = HAL_DAC_STATE_READY;
00344   }
00345 
00346   /* Return function status */
00347   return status;
00348 }
00349 
00350 
00351 /**
00352   * @brief  Enable or disable the selected DAC channel wave generation.
00353   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
00354   *         the configuration information for the specified DAC.
00355   * @param  Channel The selected DAC channel.
00356   *          This parameter can be one of the following values:
00357   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
00358   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
00359   * @param  Amplitude Select max triangle amplitude.
00360   *          This parameter can be one of the following values:
00361   *            @arg DAC_TRIANGLEAMPLITUDE_1: Select max triangle amplitude of 1
00362   *            @arg DAC_TRIANGLEAMPLITUDE_3: Select max triangle amplitude of 3
00363   *            @arg DAC_TRIANGLEAMPLITUDE_7: Select max triangle amplitude of 7
00364   *            @arg DAC_TRIANGLEAMPLITUDE_15: Select max triangle amplitude of 15
00365   *            @arg DAC_TRIANGLEAMPLITUDE_31: Select max triangle amplitude of 31
00366   *            @arg DAC_TRIANGLEAMPLITUDE_63: Select max triangle amplitude of 63
00367   *            @arg DAC_TRIANGLEAMPLITUDE_127: Select max triangle amplitude of 127
00368   *            @arg DAC_TRIANGLEAMPLITUDE_255: Select max triangle amplitude of 255
00369   *            @arg DAC_TRIANGLEAMPLITUDE_511: Select max triangle amplitude of 511
00370   *            @arg DAC_TRIANGLEAMPLITUDE_1023: Select max triangle amplitude of 1023
00371   *            @arg DAC_TRIANGLEAMPLITUDE_2047: Select max triangle amplitude of 2047
00372   *            @arg DAC_TRIANGLEAMPLITUDE_4095: Select max triangle amplitude of 4095
00373   * @retval HAL status
00374   */
00375 HAL_StatusTypeDef HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Amplitude)
00376 {
00377   /* Check the parameters */
00378   assert_param(IS_DAC_CHANNEL(Channel));
00379   assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude));
00380 
00381   /* Process locked */
00382   __HAL_LOCK(hdac);
00383 
00384   /* Change DAC state */
00385   hdac->State = HAL_DAC_STATE_BUSY;
00386 
00387   /* Enable the triangle wave generation for the selected DAC channel */
00388   MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1) | (DAC_CR_MAMP1)) << (Channel & 0x10UL),
00389              (DAC_CR_WAVE1_1 | Amplitude) << (Channel & 0x10UL));
00390 
00391   /* Change DAC state */
00392   hdac->State = HAL_DAC_STATE_READY;
00393 
00394   /* Process unlocked */
00395   __HAL_UNLOCK(hdac);
00396 
00397   /* Return function status */
00398   return HAL_OK;
00399 }
00400 
00401 /**
00402   * @brief  Enable or disable the selected DAC channel wave generation.
00403   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
00404   *         the configuration information for the specified DAC.
00405   * @param  Channel The selected DAC channel.
00406   *          This parameter can be one of the following values:
00407   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
00408   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
00409   * @param  Amplitude Unmask DAC channel LFSR for noise wave generation.
00410   *          This parameter can be one of the following values:
00411   *            @arg DAC_LFSRUNMASK_BIT0: Unmask DAC channel LFSR bit0 for noise wave generation
00412   *            @arg DAC_LFSRUNMASK_BITS1_0: Unmask DAC channel LFSR bit[1:0] for noise wave generation
00413   *            @arg DAC_LFSRUNMASK_BITS2_0: Unmask DAC channel LFSR bit[2:0] for noise wave generation
00414   *            @arg DAC_LFSRUNMASK_BITS3_0: Unmask DAC channel LFSR bit[3:0] for noise wave generation
00415   *            @arg DAC_LFSRUNMASK_BITS4_0: Unmask DAC channel LFSR bit[4:0] for noise wave generation
00416   *            @arg DAC_LFSRUNMASK_BITS5_0: Unmask DAC channel LFSR bit[5:0] for noise wave generation
00417   *            @arg DAC_LFSRUNMASK_BITS6_0: Unmask DAC channel LFSR bit[6:0] for noise wave generation
00418   *            @arg DAC_LFSRUNMASK_BITS7_0: Unmask DAC channel LFSR bit[7:0] for noise wave generation
00419   *            @arg DAC_LFSRUNMASK_BITS8_0: Unmask DAC channel LFSR bit[8:0] for noise wave generation
00420   *            @arg DAC_LFSRUNMASK_BITS9_0: Unmask DAC channel LFSR bit[9:0] for noise wave generation
00421   *            @arg DAC_LFSRUNMASK_BITS10_0: Unmask DAC channel LFSR bit[10:0] for noise wave generation
00422   *            @arg DAC_LFSRUNMASK_BITS11_0: Unmask DAC channel LFSR bit[11:0] for noise wave generation
00423   * @retval HAL status
00424   */
00425 HAL_StatusTypeDef HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Amplitude)
00426 {
00427   /* Check the parameters */
00428   assert_param(IS_DAC_CHANNEL(Channel));
00429   assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude));
00430 
00431   /* Process locked */
00432   __HAL_LOCK(hdac);
00433 
00434   /* Change DAC state */
00435   hdac->State = HAL_DAC_STATE_BUSY;
00436 
00437   /* Enable the noise wave generation for the selected DAC channel */
00438   MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1) | (DAC_CR_MAMP1)) << (Channel & 0x10UL),
00439              (DAC_CR_WAVE1_0 | Amplitude) << (Channel & 0x10UL));
00440 
00441   /* Change DAC state */
00442   hdac->State = HAL_DAC_STATE_READY;
00443 
00444   /* Process unlocked */
00445   __HAL_UNLOCK(hdac);
00446 
00447   /* Return function status */
00448   return HAL_OK;
00449 }
00450 
00451 
00452 /**
00453   * @brief  Set the specified data holding register value for dual DAC channel.
00454   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
00455   *               the configuration information for the specified DAC.
00456   * @param  Alignment Specifies the data alignment for dual channel DAC.
00457   *          This parameter can be one of the following values:
00458   *            DAC_ALIGN_8B_R: 8bit right data alignment selected
00459   *            DAC_ALIGN_12B_L: 12bit left data alignment selected
00460   *            DAC_ALIGN_12B_R: 12bit right data alignment selected
00461   * @param  Data1 Data for DAC Channel1 to be loaded in the selected data holding register.
00462   * @param  Data2 Data for DAC Channel2 to be loaded in the selected data  holding register.
00463   * @note   In dual mode, a unique register access is required to write in both
00464   *          DAC channels at the same time.
00465   * @retval HAL status
00466   */
00467 HAL_StatusTypeDef HAL_DACEx_DualSetValue(DAC_HandleTypeDef *hdac, uint32_t Alignment, uint32_t Data1, uint32_t Data2)
00468 {
00469   uint32_t data;
00470   uint32_t tmp;
00471 
00472   /* Check the parameters */
00473   assert_param(IS_DAC_ALIGN(Alignment));
00474   assert_param(IS_DAC_DATA(Data1));
00475   assert_param(IS_DAC_DATA(Data2));
00476 
00477   /* Calculate and set dual DAC data holding register value */
00478   if (Alignment == DAC_ALIGN_8B_R)
00479   {
00480     data = ((uint32_t)Data2 << 8U) | Data1;
00481   }
00482   else
00483   {
00484     data = ((uint32_t)Data2 << 16U) | Data1;
00485   }
00486 
00487   tmp = (uint32_t)hdac->Instance;
00488   tmp += DAC_DHR12RD_ALIGNMENT(Alignment);
00489 
00490   /* Set the dual DAC selected data holding register */
00491   *(__IO uint32_t *)tmp = data;
00492 
00493   /* Return function status */
00494   return HAL_OK;
00495 }
00496 
00497 /**
00498   * @brief  Conversion complete callback in non-blocking mode for Channel2.
00499   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
00500   *         the configuration information for the specified DAC.
00501   * @retval None
00502   */
00503 __weak void HAL_DACEx_ConvCpltCallbackCh2(DAC_HandleTypeDef *hdac)
00504 {
00505   /* Prevent unused argument(s) compilation warning */
00506   UNUSED(hdac);
00507 
00508   /* NOTE : This function should not be modified, when the callback is needed,
00509             the HAL_DACEx_ConvCpltCallbackCh2 could be implemented in the user file
00510    */
00511 }
00512 
00513 /**
00514   * @brief  Conversion half DMA transfer callback in non-blocking mode for Channel2.
00515   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
00516   *         the configuration information for the specified DAC.
00517   * @retval None
00518   */
00519 __weak void HAL_DACEx_ConvHalfCpltCallbackCh2(DAC_HandleTypeDef *hdac)
00520 {
00521   /* Prevent unused argument(s) compilation warning */
00522   UNUSED(hdac);
00523 
00524   /* NOTE : This function should not be modified, when the callback is needed,
00525             the HAL_DACEx_ConvHalfCpltCallbackCh2 could be implemented in the user file
00526    */
00527 }
00528 
00529 /**
00530   * @brief  Error DAC callback for Channel2.
00531   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
00532   *         the configuration information for the specified DAC.
00533   * @retval None
00534   */
00535 __weak void HAL_DACEx_ErrorCallbackCh2(DAC_HandleTypeDef *hdac)
00536 {
00537   /* Prevent unused argument(s) compilation warning */
00538   UNUSED(hdac);
00539 
00540   /* NOTE : This function should not be modified, when the callback is needed,
00541             the HAL_DACEx_ErrorCallbackCh2 could be implemented in the user file
00542    */
00543 }
00544 
00545 /**
00546   * @brief  DMA underrun DAC callback for Channel2.
00547   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
00548   *         the configuration information for the specified DAC.
00549   * @retval None
00550   */
00551 __weak void HAL_DACEx_DMAUnderrunCallbackCh2(DAC_HandleTypeDef *hdac)
00552 {
00553   /* Prevent unused argument(s) compilation warning */
00554   UNUSED(hdac);
00555 
00556   /* NOTE : This function should not be modified, when the callback is needed,
00557             the HAL_DACEx_DMAUnderrunCallbackCh2 could be implemented in the user file
00558    */
00559 }
00560 
00561 
00562 /**
00563   * @brief  Run the self calibration of one DAC channel.
00564   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
00565   *         the configuration information for the specified DAC.
00566   * @param  sConfig DAC channel configuration structure.
00567   * @param  Channel The selected DAC channel.
00568   *          This parameter can be one of the following values:
00569   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
00570   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
00571   * @retval Updates DAC_TrimmingValue. , DAC_UserTrimming set to DAC_UserTrimming
00572   * @retval HAL status
00573   * @note   Calibration runs about 7 ms.
00574   */
00575 HAL_StatusTypeDef HAL_DACEx_SelfCalibrate(DAC_HandleTypeDef *hdac, DAC_ChannelConfTypeDef *sConfig, uint32_t Channel)
00576 {
00577   HAL_StatusTypeDef status = HAL_OK;
00578 
00579   __IO uint32_t tmp;
00580   uint32_t trimmingvalue;
00581   uint32_t delta;
00582 
00583   /* store/restore channel configuration structure purpose */
00584   uint32_t oldmodeconfiguration;
00585 
00586   /* Check the parameters */
00587   assert_param(IS_DAC_CHANNEL(Channel));
00588 
00589   /* Check the DAC handle allocation */
00590   /* Check if DAC running */
00591   if (hdac == NULL)
00592   {
00593     status = HAL_ERROR;
00594   }
00595   else if (hdac->State == HAL_DAC_STATE_BUSY)
00596   {
00597     status = HAL_ERROR;
00598   }
00599   else
00600   {
00601     /* Process locked */
00602     __HAL_LOCK(hdac);
00603 
00604     /* Store configuration */
00605     oldmodeconfiguration = (hdac->Instance->MCR & (DAC_MCR_MODE1 << (Channel & 0x10UL)));
00606 
00607     /* Disable the selected DAC channel */
00608     CLEAR_BIT((hdac->Instance->CR), (DAC_CR_EN1 << (Channel & 0x10UL)));
00609 
00610     /* Set mode in MCR  for calibration */
00611     MODIFY_REG(hdac->Instance->MCR, (DAC_MCR_MODE1 << (Channel & 0x10UL)), 0U);
00612 
00613     /* Set DAC Channel1 DHR register to the middle value */
00614     tmp = (uint32_t)hdac->Instance;
00615 
00616     if (Channel == DAC_CHANNEL_1)
00617     {
00618       tmp += DAC_DHR12R1_ALIGNMENT(DAC_ALIGN_12B_R);
00619     }
00620     else
00621     {
00622       tmp += DAC_DHR12R2_ALIGNMENT(DAC_ALIGN_12B_R);
00623     }
00624 
00625     *(__IO uint32_t *) tmp = 0x0800UL;
00626 
00627     /* Enable the selected DAC channel calibration */
00628     /* i.e. set DAC_CR_CENx bit */
00629     SET_BIT((hdac->Instance->CR), (DAC_CR_CEN1 << (Channel & 0x10UL)));
00630 
00631     /* Init trimming counter */
00632     /* Medium value */
00633     trimmingvalue = 16UL;
00634     delta = 8UL;
00635     while (delta != 0UL)
00636     {
00637       /* Set candidate trimming */
00638       MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (trimmingvalue << (Channel & 0x10UL)));
00639 
00640       /* tOFFTRIMmax delay x ms as per datasheet (electrical characteristics */
00641       /* i.e. minimum time needed between two calibration steps */
00642       HAL_Delay(1);
00643 
00644       if ((hdac->Instance->SR & (DAC_SR_CAL_FLAG1 << (Channel & 0x10UL))) == (DAC_SR_CAL_FLAG1 << (Channel & 0x10UL)))
00645       {
00646         /* DAC_SR_CAL_FLAGx is HIGH try higher trimming */
00647         trimmingvalue -= delta;
00648       }
00649       else
00650       {
00651         /* DAC_SR_CAL_FLAGx is LOW try lower trimming */
00652         trimmingvalue += delta;
00653       }
00654       delta >>= 1UL;
00655     }
00656 
00657     /* Still need to check if right calibration is current value or one step below */
00658     /* Indeed the first value that causes the DAC_SR_CAL_FLAGx bit to change from 0 to 1  */
00659     /* Set candidate trimming */
00660     MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (trimmingvalue << (Channel & 0x10UL)));
00661 
00662     /* tOFFTRIMmax delay x ms as per datasheet (electrical characteristics */
00663     /* i.e. minimum time needed between two calibration steps */
00664     HAL_Delay(1U);
00665 
00666     if ((hdac->Instance->SR & (DAC_SR_CAL_FLAG1 << (Channel & 0x10UL))) == 0UL)
00667     {
00668       /* Trimming is actually one value more */
00669       trimmingvalue++;
00670       /* Set right trimming */
00671       MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (trimmingvalue << (Channel & 0x10UL)));
00672     }
00673 
00674     /* Disable the selected DAC channel calibration */
00675     /* i.e. clear DAC_CR_CENx bit */
00676     CLEAR_BIT((hdac->Instance->CR), (DAC_CR_CEN1 << (Channel & 0x10UL)));
00677 
00678     sConfig->DAC_TrimmingValue = trimmingvalue;
00679     sConfig->DAC_UserTrimming = DAC_TRIMMING_USER;
00680 
00681     /* Restore configuration */
00682     MODIFY_REG(hdac->Instance->MCR, (DAC_MCR_MODE1 << (Channel & 0x10UL)), oldmodeconfiguration);
00683 
00684     /* Process unlocked */
00685     __HAL_UNLOCK(hdac);
00686   }
00687 
00688   return status;
00689 }
00690 
00691 /**
00692   * @brief  Set the trimming mode and trimming value (user trimming mode applied).
00693   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
00694   *         the configuration information for the specified DAC.
00695   * @param  sConfig DAC configuration structure updated with new DAC trimming value.
00696   * @param  Channel The selected DAC channel.
00697   *          This parameter can be one of the following values:
00698   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
00699   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
00700   * @param  NewTrimmingValue DAC new trimming value
00701   * @retval HAL status
00702   */
00703 HAL_StatusTypeDef HAL_DACEx_SetUserTrimming(DAC_HandleTypeDef *hdac, DAC_ChannelConfTypeDef *sConfig, uint32_t Channel,
00704                                             uint32_t NewTrimmingValue)
00705 {
00706   HAL_StatusTypeDef status = HAL_OK;
00707 
00708   /* Check the parameters */
00709   assert_param(IS_DAC_CHANNEL(Channel));
00710   assert_param(IS_DAC_NEWTRIMMINGVALUE(NewTrimmingValue));
00711 
00712   /* Check the DAC handle allocation */
00713   if (hdac == NULL)
00714   {
00715     status = HAL_ERROR;
00716   }
00717   else
00718   {
00719     /* Process locked */
00720     __HAL_LOCK(hdac);
00721 
00722     /* Set new trimming */
00723     MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (NewTrimmingValue << (Channel & 0x10UL)));
00724 
00725     /* Update trimming mode */
00726     sConfig->DAC_UserTrimming = DAC_TRIMMING_USER;
00727     sConfig->DAC_TrimmingValue = NewTrimmingValue;
00728 
00729     /* Process unlocked */
00730     __HAL_UNLOCK(hdac);
00731   }
00732   return status;
00733 }
00734 
00735 /**
00736   * @brief  Return the DAC trimming value.
00737   * @param  hdac DAC handle
00738   * @param  Channel The selected DAC channel.
00739   *          This parameter can be one of the following values:
00740   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
00741   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
00742   * @retval Trimming value : range: 0->31
00743   *
00744  */
00745 uint32_t HAL_DACEx_GetTrimOffset(DAC_HandleTypeDef *hdac, uint32_t Channel)
00746 {
00747   /* Check the parameter */
00748   assert_param(IS_DAC_CHANNEL(Channel));
00749 
00750   /* Retrieve trimming */
00751   return ((hdac->Instance->CCR & (DAC_CCR_OTRIM1 << (Channel & 0x10UL))) >> (Channel & 0x10UL));
00752 }
00753 
00754 /**
00755   * @}
00756   */
00757 
00758 /** @defgroup DACEx_Exported_Functions_Group3 Peripheral Control functions
00759   *  @brief    Extended Peripheral Control functions
00760   *
00761 @verbatim
00762   ==============================================================================
00763              ##### Peripheral Control functions #####
00764   ==============================================================================
00765     [..]  This section provides functions allowing to:
00766       (+) Set the specified data holding register value for DAC channel.
00767 
00768 @endverbatim
00769   * @{
00770   */
00771 
00772 
00773 /**
00774   * @brief  Return the last data output value of the selected DAC channel.
00775   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
00776   *         the configuration information for the specified DAC.
00777   * @retval The selected DAC channel data output value.
00778   */
00779 uint32_t HAL_DACEx_DualGetValue(DAC_HandleTypeDef *hdac)
00780 {
00781   uint32_t tmp = 0UL;
00782 
00783   tmp |= hdac->Instance->DOR1;
00784 
00785   tmp |= hdac->Instance->DOR2 << 16UL;
00786 
00787   /* Returns the DAC channel data output register value */
00788   return tmp;
00789 }
00790 
00791 
00792 /**
00793   * @}
00794   */
00795 /**
00796   * @}
00797   */
00798 
00799 /* Private functions ---------------------------------------------------------*/
00800 /** @defgroup DACEx_Private_Functions DACEx private functions
00801   *  @brief    Extended private functions
00802   * @{
00803   */
00804 
00805 
00806 /**
00807   * @brief  DMA conversion complete callback.
00808   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
00809   *                the configuration information for the specified DMA module.
00810   * @retval None
00811   */
00812 void DAC_DMAConvCpltCh2(DMA_HandleTypeDef *hdma)
00813 {
00814   DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
00815 
00816 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
00817   hdac->ConvCpltCallbackCh2(hdac);
00818 #else
00819   HAL_DACEx_ConvCpltCallbackCh2(hdac);
00820 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
00821 
00822   hdac->State = HAL_DAC_STATE_READY;
00823 }
00824 
00825 /**
00826   * @brief  DMA half transfer complete callback.
00827   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
00828   *                the configuration information for the specified DMA module.
00829   * @retval None
00830   */
00831 void DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef *hdma)
00832 {
00833   DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
00834   /* Conversion complete callback */
00835 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
00836   hdac->ConvHalfCpltCallbackCh2(hdac);
00837 #else
00838   HAL_DACEx_ConvHalfCpltCallbackCh2(hdac);
00839 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
00840 }
00841 
00842 /**
00843   * @brief  DMA error callback.
00844   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
00845   *                the configuration information for the specified DMA module.
00846   * @retval None
00847   */
00848 void DAC_DMAErrorCh2(DMA_HandleTypeDef *hdma)
00849 {
00850   DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
00851 
00852   /* Set DAC error code to DMA error */
00853   hdac->ErrorCode |= HAL_DAC_ERROR_DMA;
00854 
00855 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
00856   hdac->ErrorCallbackCh2(hdac);
00857 #else
00858   HAL_DACEx_ErrorCallbackCh2(hdac);
00859 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
00860 
00861   hdac->State = HAL_DAC_STATE_READY;
00862 }
00863 
00864 
00865 /**
00866   * @}
00867   */
00868 
00869 /**
00870   * @}
00871   */
00872 
00873 #endif /* DAC1 || DAC2 */
00874 
00875 #endif /* HAL_DAC_MODULE_ENABLED */
00876 
00877 /**
00878   * @}
00879   */
00880