1 /**
2   ******************************************************************************
3   * @file    stm32g0xx_hal_dac_ex.c
4   * @author  MCD Application Team
5   * @brief   Extended DAC HAL module driver.
6   *          This file provides firmware functions to manage the extended
7   *          functionalities of the DAC peripheral.
8   *
9   *
10   ******************************************************************************
11   * @attention
12   *
13   * Copyright (c) 2018 STMicroelectronics.
14   * All rights reserved.
15   *
16   * This software is licensed under terms that can be found in the LICENSE file
17   * in the root directory of this software component.
18   * If no LICENSE file comes with this software, it is provided AS-IS.
19   *
20   ******************************************************************************
21   @verbatim
22   ==============================================================================
23                       ##### How to use this driver #####
24   ==============================================================================
25     [..]
26 
27      *** Dual mode IO operation ***
28      ==============================
29      [..]
30       (+) When Dual mode is enabled (i.e. DAC Channel1 and Channel2 are used simultaneously) :
31           Use HAL_DACEx_DualGetValue() to get digital data to be converted and use
32           HAL_DACEx_DualSetValue() to set digital value to converted simultaneously in
33           Channel 1 and Channel 2.
34 
35      *** Signal generation operation ***
36      ===================================
37      [..]
38       (+) Use HAL_DACEx_TriangleWaveGenerate() to generate Triangle signal.
39       (+) Use HAL_DACEx_NoiseWaveGenerate() to generate Noise signal.
40 
41       (+) HAL_DACEx_SelfCalibrate to calibrate one DAC channel.
42       (+) HAL_DACEx_SetUserTrimming to set user trimming value.
43       (+) HAL_DACEx_GetTrimOffset to retrieve trimming value (factory setting
44           after reset, user setting if HAL_DACEx_SetUserTrimming have been used
45           at least one time after reset).
46 
47  @endverbatim
48   ******************************************************************************
49   */
50 
51 
52 /* Includes ------------------------------------------------------------------*/
53 #include "stm32g0xx_hal.h"
54 
55 /** @addtogroup STM32G0xx_HAL_Driver
56   * @{
57   */
58 
59 #ifdef HAL_DAC_MODULE_ENABLED
60 
61 #if defined(DAC1)
62 
63 /** @defgroup DACEx DACEx
64   * @brief DAC Extended HAL module driver
65   * @{
66   */
67 
68 /* Private typedef -----------------------------------------------------------*/
69 /* Private define ------------------------------------------------------------*/
70 /* Private macro -------------------------------------------------------------*/
71 /* Private variables ---------------------------------------------------------*/
72 /* Private function prototypes -----------------------------------------------*/
73 /* Exported functions --------------------------------------------------------*/
74 
75 /** @defgroup DACEx_Exported_Functions DACEx Exported Functions
76   * @{
77   */
78 
79 /** @defgroup DACEx_Exported_Functions_Group2 IO operation functions
80   *  @brief    Extended IO operation functions
81   *
82 @verbatim
83   ==============================================================================
84                  ##### Extended features functions #####
85   ==============================================================================
86     [..]  This section provides functions allowing to:
87       (+) Start conversion.
88       (+) Stop conversion.
89       (+) Start conversion and enable DMA transfer.
90       (+) Stop conversion and disable DMA transfer.
91       (+) Get result of conversion.
92       (+) Get result of dual mode conversion.
93 
94 @endverbatim
95   * @{
96   */
97 
98 
99 /**
100   * @brief  Enables DAC and starts conversion of both channels.
101   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
102   *         the configuration information for the specified DAC.
103   * @retval HAL status
104   */
HAL_DACEx_DualStart(DAC_HandleTypeDef * hdac)105 HAL_StatusTypeDef HAL_DACEx_DualStart(DAC_HandleTypeDef *hdac)
106 {
107   uint32_t tmp_swtrig = 0UL;
108 
109 
110   /* Process locked */
111   __HAL_LOCK(hdac);
112 
113   /* Change DAC state */
114   hdac->State = HAL_DAC_STATE_BUSY;
115 
116   /* Enable the Peripheral */
117   __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_1);
118   __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_2);
119 
120   /* Check if software trigger enabled */
121   if ((hdac->Instance->CR & (DAC_CR_TEN1 | DAC_CR_TSEL1)) == DAC_TRIGGER_SOFTWARE)
122   {
123     tmp_swtrig |= DAC_SWTRIGR_SWTRIG1;
124   }
125   if ((hdac->Instance->CR & (DAC_CR_TEN2 | DAC_CR_TSEL2)) == (DAC_TRIGGER_SOFTWARE << (DAC_CHANNEL_2 & 0x10UL)))
126   {
127     tmp_swtrig |= DAC_SWTRIGR_SWTRIG2;
128   }
129   /* Enable the selected DAC software conversion*/
130   SET_BIT(hdac->Instance->SWTRIGR, tmp_swtrig);
131 
132   /* Change DAC state */
133   hdac->State = HAL_DAC_STATE_READY;
134 
135   /* Process unlocked */
136   __HAL_UNLOCK(hdac);
137 
138   /* Return function status */
139   return HAL_OK;
140 }
141 
142 /**
143   * @brief  Disables DAC and stop conversion of both channels.
144   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
145   *         the configuration information for the specified DAC.
146   * @retval HAL status
147   */
HAL_DACEx_DualStop(DAC_HandleTypeDef * hdac)148 HAL_StatusTypeDef HAL_DACEx_DualStop(DAC_HandleTypeDef *hdac)
149 {
150 
151   /* Disable the Peripheral */
152   __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_1);
153   __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_2);
154 
155   /* Change DAC state */
156   hdac->State = HAL_DAC_STATE_READY;
157 
158   /* Return function status */
159   return HAL_OK;
160 }
161 
162 
163 /**
164   * @brief  Enable or disable the selected DAC channel wave generation.
165   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
166   *         the configuration information for the specified DAC.
167   * @param  Channel The selected DAC channel.
168   *          This parameter can be one of the following values:
169   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
170   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
171   * @param  Amplitude Select max triangle amplitude.
172   *          This parameter can be one of the following values:
173   *            @arg DAC_TRIANGLEAMPLITUDE_1: Select max triangle amplitude of 1
174   *            @arg DAC_TRIANGLEAMPLITUDE_3: Select max triangle amplitude of 3
175   *            @arg DAC_TRIANGLEAMPLITUDE_7: Select max triangle amplitude of 7
176   *            @arg DAC_TRIANGLEAMPLITUDE_15: Select max triangle amplitude of 15
177   *            @arg DAC_TRIANGLEAMPLITUDE_31: Select max triangle amplitude of 31
178   *            @arg DAC_TRIANGLEAMPLITUDE_63: Select max triangle amplitude of 63
179   *            @arg DAC_TRIANGLEAMPLITUDE_127: Select max triangle amplitude of 127
180   *            @arg DAC_TRIANGLEAMPLITUDE_255: Select max triangle amplitude of 255
181   *            @arg DAC_TRIANGLEAMPLITUDE_511: Select max triangle amplitude of 511
182   *            @arg DAC_TRIANGLEAMPLITUDE_1023: Select max triangle amplitude of 1023
183   *            @arg DAC_TRIANGLEAMPLITUDE_2047: Select max triangle amplitude of 2047
184   *            @arg DAC_TRIANGLEAMPLITUDE_4095: Select max triangle amplitude of 4095
185   * @retval HAL status
186   */
HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef * hdac,uint32_t Channel,uint32_t Amplitude)187 HAL_StatusTypeDef HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Amplitude)
188 {
189   /* Check the parameters */
190   assert_param(IS_DAC_CHANNEL(Channel));
191   assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude));
192 
193   /* Process locked */
194   __HAL_LOCK(hdac);
195 
196   /* Change DAC state */
197   hdac->State = HAL_DAC_STATE_BUSY;
198 
199   /* Enable the triangle wave generation for the selected DAC channel */
200   MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1) | (DAC_CR_MAMP1)) << (Channel & 0x10UL),
201              (DAC_CR_WAVE1_1 | Amplitude) << (Channel & 0x10UL));
202 
203   /* Change DAC state */
204   hdac->State = HAL_DAC_STATE_READY;
205 
206   /* Process unlocked */
207   __HAL_UNLOCK(hdac);
208 
209   /* Return function status */
210   return HAL_OK;
211 }
212 
213 /**
214   * @brief  Enable or disable the selected DAC channel wave generation.
215   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
216   *         the configuration information for the specified DAC.
217   * @param  Channel The selected DAC channel.
218   *          This parameter can be one of the following values:
219   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
220   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
221   * @param  Amplitude Unmask DAC channel LFSR for noise wave generation.
222   *          This parameter can be one of the following values:
223   *            @arg DAC_LFSRUNMASK_BIT0: Unmask DAC channel LFSR bit0 for noise wave generation
224   *            @arg DAC_LFSRUNMASK_BITS1_0: Unmask DAC channel LFSR bit[1:0] for noise wave generation
225   *            @arg DAC_LFSRUNMASK_BITS2_0: Unmask DAC channel LFSR bit[2:0] for noise wave generation
226   *            @arg DAC_LFSRUNMASK_BITS3_0: Unmask DAC channel LFSR bit[3:0] for noise wave generation
227   *            @arg DAC_LFSRUNMASK_BITS4_0: Unmask DAC channel LFSR bit[4:0] for noise wave generation
228   *            @arg DAC_LFSRUNMASK_BITS5_0: Unmask DAC channel LFSR bit[5:0] for noise wave generation
229   *            @arg DAC_LFSRUNMASK_BITS6_0: Unmask DAC channel LFSR bit[6:0] for noise wave generation
230   *            @arg DAC_LFSRUNMASK_BITS7_0: Unmask DAC channel LFSR bit[7:0] for noise wave generation
231   *            @arg DAC_LFSRUNMASK_BITS8_0: Unmask DAC channel LFSR bit[8:0] for noise wave generation
232   *            @arg DAC_LFSRUNMASK_BITS9_0: Unmask DAC channel LFSR bit[9:0] for noise wave generation
233   *            @arg DAC_LFSRUNMASK_BITS10_0: Unmask DAC channel LFSR bit[10:0] for noise wave generation
234   *            @arg DAC_LFSRUNMASK_BITS11_0: Unmask DAC channel LFSR bit[11:0] for noise wave generation
235   * @retval HAL status
236   */
HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef * hdac,uint32_t Channel,uint32_t Amplitude)237 HAL_StatusTypeDef HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Amplitude)
238 {
239   /* Check the parameters */
240   assert_param(IS_DAC_CHANNEL(Channel));
241   assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude));
242 
243   /* Process locked */
244   __HAL_LOCK(hdac);
245 
246   /* Change DAC state */
247   hdac->State = HAL_DAC_STATE_BUSY;
248 
249   /* Enable the noise wave generation for the selected DAC channel */
250   MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1) | (DAC_CR_MAMP1)) << (Channel & 0x10UL),
251              (DAC_CR_WAVE1_0 | Amplitude) << (Channel & 0x10UL));
252 
253   /* Change DAC state */
254   hdac->State = HAL_DAC_STATE_READY;
255 
256   /* Process unlocked */
257   __HAL_UNLOCK(hdac);
258 
259   /* Return function status */
260   return HAL_OK;
261 }
262 
263 
264 /**
265   * @brief  Set the specified data holding register value for dual DAC channel.
266   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
267   *               the configuration information for the specified DAC.
268   * @param  Alignment Specifies the data alignment for dual channel DAC.
269   *          This parameter can be one of the following values:
270   *            DAC_ALIGN_8B_R: 8bit right data alignment selected
271   *            DAC_ALIGN_12B_L: 12bit left data alignment selected
272   *            DAC_ALIGN_12B_R: 12bit right data alignment selected
273   * @param  Data1 Data for DAC Channel1 to be loaded in the selected data holding register.
274   * @param  Data2 Data for DAC Channel2 to be loaded in the selected data  holding register.
275   * @note   In dual mode, a unique register access is required to write in both
276   *          DAC channels at the same time.
277   * @retval HAL status
278   */
HAL_DACEx_DualSetValue(DAC_HandleTypeDef * hdac,uint32_t Alignment,uint32_t Data1,uint32_t Data2)279 HAL_StatusTypeDef HAL_DACEx_DualSetValue(DAC_HandleTypeDef *hdac, uint32_t Alignment, uint32_t Data1, uint32_t Data2)
280 {
281   uint32_t data;
282   uint32_t tmp;
283 
284   /* Check the parameters */
285   assert_param(IS_DAC_ALIGN(Alignment));
286   assert_param(IS_DAC_DATA(Data1));
287   assert_param(IS_DAC_DATA(Data2));
288 
289   /* Calculate and set dual DAC data holding register value */
290   if (Alignment == DAC_ALIGN_8B_R)
291   {
292     data = ((uint32_t)Data2 << 8U) | Data1;
293   }
294   else
295   {
296     data = ((uint32_t)Data2 << 16U) | Data1;
297   }
298 
299   tmp = (uint32_t)hdac->Instance;
300   tmp += DAC_DHR12RD_ALIGNMENT(Alignment);
301 
302   /* Set the dual DAC selected data holding register */
303   *(__IO uint32_t *)tmp = data;
304 
305   /* Return function status */
306   return HAL_OK;
307 }
308 
309 /**
310   * @brief  Conversion complete callback in non-blocking mode for Channel2.
311   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
312   *         the configuration information for the specified DAC.
313   * @retval None
314   */
HAL_DACEx_ConvCpltCallbackCh2(DAC_HandleTypeDef * hdac)315 __weak void HAL_DACEx_ConvCpltCallbackCh2(DAC_HandleTypeDef *hdac)
316 {
317   /* Prevent unused argument(s) compilation warning */
318   UNUSED(hdac);
319 
320   /* NOTE : This function should not be modified, when the callback is needed,
321             the HAL_DACEx_ConvCpltCallbackCh2 could be implemented in the user file
322    */
323 }
324 
325 /**
326   * @brief  Conversion half DMA transfer callback in non-blocking mode for Channel2.
327   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
328   *         the configuration information for the specified DAC.
329   * @retval None
330   */
HAL_DACEx_ConvHalfCpltCallbackCh2(DAC_HandleTypeDef * hdac)331 __weak void HAL_DACEx_ConvHalfCpltCallbackCh2(DAC_HandleTypeDef *hdac)
332 {
333   /* Prevent unused argument(s) compilation warning */
334   UNUSED(hdac);
335 
336   /* NOTE : This function should not be modified, when the callback is needed,
337             the HAL_DACEx_ConvHalfCpltCallbackCh2 could be implemented in the user file
338    */
339 }
340 
341 /**
342   * @brief  Error DAC callback for Channel2.
343   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
344   *         the configuration information for the specified DAC.
345   * @retval None
346   */
HAL_DACEx_ErrorCallbackCh2(DAC_HandleTypeDef * hdac)347 __weak void HAL_DACEx_ErrorCallbackCh2(DAC_HandleTypeDef *hdac)
348 {
349   /* Prevent unused argument(s) compilation warning */
350   UNUSED(hdac);
351 
352   /* NOTE : This function should not be modified, when the callback is needed,
353             the HAL_DACEx_ErrorCallbackCh2 could be implemented in the user file
354    */
355 }
356 
357 /**
358   * @brief  DMA underrun DAC callback for Channel2.
359   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
360   *         the configuration information for the specified DAC.
361   * @retval None
362   */
HAL_DACEx_DMAUnderrunCallbackCh2(DAC_HandleTypeDef * hdac)363 __weak void HAL_DACEx_DMAUnderrunCallbackCh2(DAC_HandleTypeDef *hdac)
364 {
365   /* Prevent unused argument(s) compilation warning */
366   UNUSED(hdac);
367 
368   /* NOTE : This function should not be modified, when the callback is needed,
369             the HAL_DACEx_DMAUnderrunCallbackCh2 could be implemented in the user file
370    */
371 }
372 
373 
374 /**
375   * @brief  Run the self calibration of one DAC channel.
376   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
377   *         the configuration information for the specified DAC.
378   * @param  sConfig DAC channel configuration structure.
379   * @param  Channel The selected DAC channel.
380   *          This parameter can be one of the following values:
381   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
382   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
383   * @retval Updates DAC_TrimmingValue. , DAC_UserTrimming set to DAC_UserTrimming
384   * @retval HAL status
385   * @note   Calibration runs about 7 ms.
386   */
HAL_DACEx_SelfCalibrate(DAC_HandleTypeDef * hdac,DAC_ChannelConfTypeDef * sConfig,uint32_t Channel)387 HAL_StatusTypeDef HAL_DACEx_SelfCalibrate(DAC_HandleTypeDef *hdac, DAC_ChannelConfTypeDef *sConfig, uint32_t Channel)
388 {
389   HAL_StatusTypeDef status = HAL_OK;
390 
391   __IO uint32_t tmp;
392   uint32_t trimmingvalue;
393   uint32_t delta;
394 
395   /* store/restore channel configuration structure purpose */
396   uint32_t oldmodeconfiguration;
397 
398   /* Check the parameters */
399   assert_param(IS_DAC_CHANNEL(Channel));
400 
401   /* Check the DAC handle allocation */
402   /* Check if DAC running */
403   if (hdac == NULL)
404   {
405     status = HAL_ERROR;
406   }
407   else if (hdac->State == HAL_DAC_STATE_BUSY)
408   {
409     status = HAL_ERROR;
410   }
411   else
412   {
413     /* Process locked */
414     __HAL_LOCK(hdac);
415 
416     /* Store configuration */
417     oldmodeconfiguration = (hdac->Instance->MCR & (DAC_MCR_MODE1 << (Channel & 0x10UL)));
418 
419     /* Disable the selected DAC channel */
420     CLEAR_BIT((hdac->Instance->CR), (DAC_CR_EN1 << (Channel & 0x10UL)));
421 
422     /* Set mode in MCR  for calibration */
423     MODIFY_REG(hdac->Instance->MCR, (DAC_MCR_MODE1 << (Channel & 0x10UL)), 0U);
424 
425     /* Set DAC Channel1 DHR register to the middle value */
426     tmp = (uint32_t)hdac->Instance;
427 
428     if (Channel == DAC_CHANNEL_1)
429     {
430       tmp += DAC_DHR12R1_ALIGNMENT(DAC_ALIGN_12B_R);
431     }
432     else
433     {
434       tmp += DAC_DHR12R2_ALIGNMENT(DAC_ALIGN_12B_R);
435     }
436 
437     *(__IO uint32_t *) tmp = 0x0800UL;
438 
439     /* Enable the selected DAC channel calibration */
440     /* i.e. set DAC_CR_CENx bit */
441     SET_BIT((hdac->Instance->CR), (DAC_CR_CEN1 << (Channel & 0x10UL)));
442 
443     /* Init trimming counter */
444     /* Medium value */
445     trimmingvalue = 16UL;
446     delta = 8UL;
447     while (delta != 0UL)
448     {
449       /* Set candidate trimming */
450       MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (trimmingvalue << (Channel & 0x10UL)));
451 
452       /* tOFFTRIMmax delay x ms as per datasheet (electrical characteristics */
453       /* i.e. minimum time needed between two calibration steps */
454       HAL_Delay(1);
455 
456       if ((hdac->Instance->SR & (DAC_SR_CAL_FLAG1 << (Channel & 0x10UL))) == (DAC_SR_CAL_FLAG1 << (Channel & 0x10UL)))
457       {
458         /* DAC_SR_CAL_FLAGx is HIGH try higher trimming */
459         trimmingvalue -= delta;
460       }
461       else
462       {
463         /* DAC_SR_CAL_FLAGx is LOW try lower trimming */
464         trimmingvalue += delta;
465       }
466       delta >>= 1UL;
467     }
468 
469     /* Still need to check if right calibration is current value or one step below */
470     /* Indeed the first value that causes the DAC_SR_CAL_FLAGx bit to change from 0 to 1  */
471     /* Set candidate trimming */
472     MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (trimmingvalue << (Channel & 0x10UL)));
473 
474     /* tOFFTRIMmax delay x ms as per datasheet (electrical characteristics */
475     /* i.e. minimum time needed between two calibration steps */
476     HAL_Delay(1U);
477 
478     if ((hdac->Instance->SR & (DAC_SR_CAL_FLAG1 << (Channel & 0x10UL))) == 0UL)
479     {
480       /* Trimming is actually one value more */
481       trimmingvalue++;
482       /* Set right trimming */
483       MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (trimmingvalue << (Channel & 0x10UL)));
484     }
485 
486     /* Disable the selected DAC channel calibration */
487     /* i.e. clear DAC_CR_CENx bit */
488     CLEAR_BIT((hdac->Instance->CR), (DAC_CR_CEN1 << (Channel & 0x10UL)));
489 
490     sConfig->DAC_TrimmingValue = trimmingvalue;
491     sConfig->DAC_UserTrimming = DAC_TRIMMING_USER;
492 
493     /* Restore configuration */
494     MODIFY_REG(hdac->Instance->MCR, (DAC_MCR_MODE1 << (Channel & 0x10UL)), oldmodeconfiguration);
495 
496     /* Process unlocked */
497     __HAL_UNLOCK(hdac);
498   }
499 
500   return status;
501 }
502 
503 /**
504   * @brief  Set the trimming mode and trimming value (user trimming mode applied).
505   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
506   *         the configuration information for the specified DAC.
507   * @param  sConfig DAC configuration structure updated with new DAC trimming value.
508   * @param  Channel The selected DAC channel.
509   *          This parameter can be one of the following values:
510   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
511   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
512   * @param  NewTrimmingValue DAC new trimming value
513   * @retval HAL status
514   */
HAL_DACEx_SetUserTrimming(DAC_HandleTypeDef * hdac,DAC_ChannelConfTypeDef * sConfig,uint32_t Channel,uint32_t NewTrimmingValue)515 HAL_StatusTypeDef HAL_DACEx_SetUserTrimming(DAC_HandleTypeDef *hdac, DAC_ChannelConfTypeDef *sConfig, uint32_t Channel,
516                                             uint32_t NewTrimmingValue)
517 {
518   HAL_StatusTypeDef status = HAL_OK;
519 
520   /* Check the parameters */
521   assert_param(IS_DAC_CHANNEL(Channel));
522   assert_param(IS_DAC_NEWTRIMMINGVALUE(NewTrimmingValue));
523 
524   /* Check the DAC handle allocation */
525   if (hdac == NULL)
526   {
527     status = HAL_ERROR;
528   }
529   else
530   {
531     /* Process locked */
532     __HAL_LOCK(hdac);
533 
534     /* Set new trimming */
535     MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (NewTrimmingValue << (Channel & 0x10UL)));
536 
537     /* Update trimming mode */
538     sConfig->DAC_UserTrimming = DAC_TRIMMING_USER;
539     sConfig->DAC_TrimmingValue = NewTrimmingValue;
540 
541     /* Process unlocked */
542     __HAL_UNLOCK(hdac);
543   }
544   return status;
545 }
546 
547 /**
548   * @brief  Return the DAC trimming value.
549   * @param  hdac DAC handle
550   * @param  Channel The selected DAC channel.
551   *          This parameter can be one of the following values:
552   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
553   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
554   * @retval Trimming value : range: 0->31
555   *
556  */
HAL_DACEx_GetTrimOffset(DAC_HandleTypeDef * hdac,uint32_t Channel)557 uint32_t HAL_DACEx_GetTrimOffset(DAC_HandleTypeDef *hdac, uint32_t Channel)
558 {
559   /* Check the parameter */
560   assert_param(IS_DAC_CHANNEL(Channel));
561 
562   /* Retrieve trimming */
563   return ((hdac->Instance->CCR & (DAC_CCR_OTRIM1 << (Channel & 0x10UL))) >> (Channel & 0x10UL));
564 }
565 
566 /**
567   * @}
568   */
569 
570 /** @defgroup DACEx_Exported_Functions_Group3 Peripheral Control functions
571   *  @brief    Extended Peripheral Control functions
572   *
573 @verbatim
574   ==============================================================================
575              ##### Peripheral Control functions #####
576   ==============================================================================
577     [..]  This section provides functions allowing to:
578       (+) Set the specified data holding register value for DAC channel.
579 
580 @endverbatim
581   * @{
582   */
583 
584 
585 /**
586   * @brief  Return the last data output value of the selected DAC channel.
587   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
588   *         the configuration information for the specified DAC.
589   * @retval The selected DAC channel data output value.
590   */
HAL_DACEx_DualGetValue(DAC_HandleTypeDef * hdac)591 uint32_t HAL_DACEx_DualGetValue(DAC_HandleTypeDef *hdac)
592 {
593   uint32_t tmp = 0UL;
594 
595   tmp |= hdac->Instance->DOR1;
596 
597   tmp |= hdac->Instance->DOR2 << 16UL;
598 
599   /* Returns the DAC channel data output register value */
600   return tmp;
601 }
602 
603 
604 /**
605   * @}
606   */
607 /**
608   * @}
609   */
610 
611 /* Private functions ---------------------------------------------------------*/
612 /** @defgroup DACEx_Private_Functions DACEx private functions
613   *  @brief    Extended private functions
614   * @{
615   */
616 
617 
618 /**
619   * @brief  DMA conversion complete callback.
620   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
621   *                the configuration information for the specified DMA module.
622   * @retval None
623   */
DAC_DMAConvCpltCh2(DMA_HandleTypeDef * hdma)624 void DAC_DMAConvCpltCh2(DMA_HandleTypeDef *hdma)
625 {
626   DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
627 
628 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
629   hdac->ConvCpltCallbackCh2(hdac);
630 #else
631   HAL_DACEx_ConvCpltCallbackCh2(hdac);
632 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
633 
634   hdac->State = HAL_DAC_STATE_READY;
635 }
636 
637 /**
638   * @brief  DMA half transfer complete callback.
639   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
640   *                the configuration information for the specified DMA module.
641   * @retval None
642   */
DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef * hdma)643 void DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef *hdma)
644 {
645   DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
646   /* Conversion complete callback */
647 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
648   hdac->ConvHalfCpltCallbackCh2(hdac);
649 #else
650   HAL_DACEx_ConvHalfCpltCallbackCh2(hdac);
651 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
652 }
653 
654 /**
655   * @brief  DMA error callback.
656   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
657   *                the configuration information for the specified DMA module.
658   * @retval None
659   */
DAC_DMAErrorCh2(DMA_HandleTypeDef * hdma)660 void DAC_DMAErrorCh2(DMA_HandleTypeDef *hdma)
661 {
662   DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
663 
664   /* Set DAC error code to DMA error */
665   hdac->ErrorCode |= HAL_DAC_ERROR_DMA;
666 
667 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
668   hdac->ErrorCallbackCh2(hdac);
669 #else
670   HAL_DACEx_ErrorCallbackCh2(hdac);
671 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
672 
673   hdac->State = HAL_DAC_STATE_READY;
674 }
675 
676 
677 /**
678   * @}
679   */
680 
681 /**
682   * @}
683   */
684 
685 #endif /* DAC1 */
686 
687 #endif /* HAL_DAC_MODULE_ENABLED */
688 
689 /**
690   * @}
691   */
692 
693