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