1 /**
2   ******************************************************************************
3   * @file    stm32l0xx_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 following
7   *          functionalities of DAC extension peripheral:
8   *           + Extended features functions
9   *
10   *
11   ******************************************************************************
12   * @attention
13   *
14   * Copyright (c) 2016 STMicroelectronics.
15   * All rights reserved.
16   *
17   * This software is licensed under terms that can be found in the LICENSE file
18   * in the root directory of this software component.
19   * If no LICENSE file comes with this software, it is provided AS-IS.
20   *
21   ******************************************************************************
22   @verbatim
23   ==============================================================================
24                       ##### How to use this driver #####
25   ==============================================================================
26     [..]
27       (+) When Dual mode is enabled (i.e DAC Channel1 and Channel2 are used simultaneously) :
28           Use HAL_DACEx_DualGetValue() to get digital data to be converted and use
29           HAL_DACEx_DualSetValue() to set digital value to converted simultaneously in Channel 1 and Channel 2.
30       (+) Use HAL_DACEx_TriangleWaveGenerate() to generate Triangle signal.
31       (+) Use HAL_DACEx_NoiseWaveGenerate() to generate Noise signal.
32 
33  @endverbatim
34   ******************************************************************************
35   */
36 
37 
38 #if !defined (STM32L010xB) && !defined (STM32L010x8) && !defined (STM32L010x6) && !defined (STM32L010x4) && !defined (STM32L011xx) && !defined (STM32L021xx) && !defined (STM32L031xx) && !defined (STM32L041xx) && !defined (STM32L051xx) && !defined (STM32L071xx) && !defined (STM32L081xx)
39 /* Includes ------------------------------------------------------------------*/
40 #include "stm32l0xx_hal.h"
41 
42 #ifdef HAL_DAC_MODULE_ENABLED
43 /** @addtogroup STM32L0xx_HAL_Driver
44   * @{
45   */
46 
47 /** @addtogroup DACEx DACEx
48   * @brief DAC driver modules
49   * @{
50   */
51 
52 /** @addtogroup DACEx_Private
53   * @{
54   */
55 
56 /* Private typedef -----------------------------------------------------------*/
57 /* Private define ------------------------------------------------------------*/
58 /* Private macro -------------------------------------------------------------*/
59 /* Private variables ---------------------------------------------------------*/
60 /* Private function prototypes -----------------------------------------------*/
61 /* Private functions ---------------------------------------------------------*/
62 
63 #if defined (STM32L072xx) || defined (STM32L073xx) || defined (STM32L082xx) || defined (STM32L083xx)
64 static void DAC_DMAConvCpltCh2(DMA_HandleTypeDef *hdma);
65 static void DAC_DMAErrorCh2(DMA_HandleTypeDef *hdma);
66 static void DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef *hdma);
67 #endif
68 static void DAC_DMAConvCpltCh1(DMA_HandleTypeDef *hdma);
69 static void DAC_DMAErrorCh1(DMA_HandleTypeDef *hdma);
70 static void DAC_DMAHalfConvCpltCh1(DMA_HandleTypeDef *hdma);
71 /**
72   * @}
73   */
74 
75 /** @addtogroup DACEx_Exported_Functions
76   * @{
77   */
78 
79 /** @addtogroup DACEx_Exported_Functions_Group1
80  *  @brief    Extended features functions
81  *
82 
83   * @{
84   */
85 
86 #if defined (STM32L072xx) || defined (STM32L073xx) || defined (STM32L082xx) || defined (STM32L083xx)
87 /**
88   * @brief  Returns the last data output value of the selected DAC channel.
89   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
90   *         the configuration information for the specified DAC.
91   * @retval The selected DAC channel data output value.
92   */
HAL_DACEx_DualGetValue(DAC_HandleTypeDef * hdac)93 uint32_t HAL_DACEx_DualGetValue(DAC_HandleTypeDef* hdac)
94 {
95   uint32_t tmp = 0U;
96 
97   tmp |= hdac->Instance->DOR1;
98 
99   tmp |= hdac->Instance->DOR2 << 16U;
100 
101   /* Returns the DAC channel data output register value */
102   return tmp;
103 }
104 #endif
105 
106 /**
107   * @brief  Enable or disable the selected DAC channel wave generation.
108   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
109   *         the configuration information for the specified DAC.
110   * @param  Channel The selected DAC channel.
111   *          This parameter can be one of the following values:
112   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
113   *            @arg DAC_CHANNEL_2: DAC Channel2 selected (STM32L07x/STM32L08x only)
114   * @param  Amplitude Select max triangle amplitude.
115   *          This parameter can be one of the following values:
116   *            @arg DAC_TRIANGLEAMPLITUDE_1: Select max triangle amplitude of 1
117   *            @arg DAC_TRIANGLEAMPLITUDE_3: Select max triangle amplitude of 3
118   *            @arg DAC_TRIANGLEAMPLITUDE_7: Select max triangle amplitude of 7
119   *            @arg DAC_TRIANGLEAMPLITUDE_15: Select max triangle amplitude of 15
120   *            @arg DAC_TRIANGLEAMPLITUDE_31: Select max triangle amplitude of 31
121   *            @arg DAC_TRIANGLEAMPLITUDE_63: Select max triangle amplitude of 63
122   *            @arg DAC_TRIANGLEAMPLITUDE_127: Select max triangle amplitude of 127
123   *            @arg DAC_TRIANGLEAMPLITUDE_255: Select max triangle amplitude of 255
124   *            @arg DAC_TRIANGLEAMPLITUDE_511: Select max triangle amplitude of 511
125   *            @arg DAC_TRIANGLEAMPLITUDE_1023: Select max triangle amplitude of 1023
126   *            @arg DAC_TRIANGLEAMPLITUDE_2047: Select max triangle amplitude of 2047
127   *            @arg DAC_TRIANGLEAMPLITUDE_4095: Select max triangle amplitude of 4095
128   * @retval HAL status
129   */
HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef * hdac,uint32_t Channel,uint32_t Amplitude)130 HAL_StatusTypeDef HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Amplitude)
131 {
132   /* Check the parameters */
133   assert_param(IS_DAC_CHANNEL(Channel));
134   assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude));
135 
136   /* Process locked */
137   __HAL_LOCK(hdac);
138 
139   /* Change DAC state */
140   hdac->State = HAL_DAC_STATE_BUSY;
141 
142   /* Enable the triangle wave generation for the selected DAC channel */
143   MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1)|(DAC_CR_MAMP1))<<Channel, (DAC_CR_WAVE1_1 | Amplitude) << Channel);
144 
145 
146   /* Change DAC state */
147   hdac->State = HAL_DAC_STATE_READY;
148 
149   /* Process unlocked */
150   __HAL_UNLOCK(hdac);
151 
152   /* Return function status */
153   return HAL_OK;
154 }
155 
156 /**
157   * @brief  Enable or disable the selected DAC channel wave generation.
158   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
159   *         the configuration information for the specified DAC.
160   * @param  Channel The selected DAC channel.
161   *          This parameter can be one of the following values:
162   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
163   *            @arg DAC_CHANNEL_2: DAC Channel2 selected (STM32L07x/STM32L08x only)
164   * @param  Amplitude Unmask DAC channel LFSR for noise wave generation.
165   *          This parameter can be one of the following values:
166   *            @arg DAC_LFSRUNMASK_BIT0: Unmask DAC channel LFSR bit0 for noise wave generation
167   *            @arg DAC_LFSRUNMASK_BITS1_0: Unmask DAC channel LFSR bit[1:0] for noise wave generation
168   *            @arg DAC_LFSRUNMASK_BITS2_0: Unmask DAC channel LFSR bit[2:0] for noise wave generation
169   *            @arg DAC_LFSRUNMASK_BITS3_0: Unmask DAC channel LFSR bit[3:0] for noise wave generation
170   *            @arg DAC_LFSRUNMASK_BITS4_0: Unmask DAC channel LFSR bit[4:0] for noise wave generation
171   *            @arg DAC_LFSRUNMASK_BITS5_0: Unmask DAC channel LFSR bit[5:0] for noise wave generation
172   *            @arg DAC_LFSRUNMASK_BITS6_0: Unmask DAC channel LFSR bit[6:0] for noise wave generation
173   *            @arg DAC_LFSRUNMASK_BITS7_0: Unmask DAC channel LFSR bit[7:0] for noise wave generation
174   *            @arg DAC_LFSRUNMASK_BITS8_0: Unmask DAC channel LFSR bit[8:0] for noise wave generation
175   *            @arg DAC_LFSRUNMASK_BITS9_0: Unmask DAC channel LFSR bit[9:0] for noise wave generation
176   *            @arg DAC_LFSRUNMASK_BITS10_0: Unmask DAC channel LFSR bit[10:0] for noise wave generation
177   *            @arg DAC_LFSRUNMASK_BITS11_0: Unmask DAC channel LFSR bit[11:0] for noise wave generation
178   * @retval HAL status
179   */
HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef * hdac,uint32_t Channel,uint32_t Amplitude)180 HAL_StatusTypeDef HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Amplitude)
181 {
182   /* Check the parameters */
183   assert_param(IS_DAC_CHANNEL(Channel));
184   assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude));
185 
186   /* Process locked */
187   __HAL_LOCK(hdac);
188 
189   /* Change DAC state */
190   hdac->State = HAL_DAC_STATE_BUSY;
191 
192 /* Enable the noise wave generation for the selected DAC channel */
193   MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1)|(DAC_CR_MAMP1))<<Channel, (DAC_CR_WAVE1_0 | Amplitude) << Channel);
194 
195   /* Change DAC state */
196   hdac->State = HAL_DAC_STATE_READY;
197 
198   /* Process unlocked */
199   __HAL_UNLOCK(hdac);
200 
201   /* Return function status */
202   return HAL_OK;
203 }
204 
205 #if defined (STM32L072xx) || defined (STM32L073xx) || defined (STM32L082xx) || defined (STM32L083xx)
206 /**
207   * @brief  Set the specified data holding register value for dual DAC channel.
208   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
209   *               the configuration information for the specified DAC.
210   * @param  Alignment Specifies the data alignment for dual channel DAC.
211   *          This parameter can be one of the following values:
212   *            DAC_ALIGN_8B_R: 8bit right data alignment selected
213   *            DAC_ALIGN_12B_L: 12bit left data alignment selected
214   *            DAC_ALIGN_12B_R: 12bit right data alignment selected
215   * @param  Data1 Data for DAC Channel1 to be loaded in the selected data holding register.
216   * @param  Data2 Data for DAC Channel2 to be loaded in the selected data holding register.
217   * @note   In dual mode, a unique register access is required to write in both
218   *          DAC channels at the same time.
219   * @retval HAL status
220   */
HAL_DACEx_DualSetValue(DAC_HandleTypeDef * hdac,uint32_t Alignment,uint32_t Data1,uint32_t Data2)221 HAL_StatusTypeDef HAL_DACEx_DualSetValue(DAC_HandleTypeDef* hdac, uint32_t Alignment, uint32_t Data1, uint32_t Data2)
222 {
223   uint32_t data = 0U, tmp = 0U;
224 
225   /* Check the parameters */
226   assert_param(IS_DAC_ALIGN(Alignment));
227   assert_param(IS_DAC_DATA(Data1));
228   assert_param(IS_DAC_DATA(Data2));
229 
230   /* Calculate and set dual DAC data holding register value */
231   if (Alignment == DAC_ALIGN_8B_R)
232   {
233     data = ((uint32_t)Data2 << 8U) | Data1;
234   }
235   else
236   {
237     data = ((uint32_t)Data2 << 16U) | Data1;
238   }
239 
240   tmp = (uint32_t)hdac->Instance;
241   tmp += DAC_DHR12RD_ALIGNMENT(Alignment);
242 
243   /* Set the dual DAC selected data holding register */
244   *(__IO uint32_t *)tmp = data;
245 
246   /* Return function status */
247   return HAL_OK;
248 }
249 
250 /**
251   * @brief  Conversion complete callback in non blocking mode for Channel2
252   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
253   *         the configuration information for the specified DAC.
254   * @retval None
255   */
HAL_DACEx_ConvCpltCallbackCh2(DAC_HandleTypeDef * hdac)256 __weak void HAL_DACEx_ConvCpltCallbackCh2(DAC_HandleTypeDef* hdac)
257 {
258   /* Prevent unused argument(s) compilation warning */
259   UNUSED(hdac);
260 
261   /* NOTE : This function should not be modified, when the callback is needed,
262             the HAL_DACEx_ConvCpltCallbackCh2 could be implemented in the user file
263    */
264 }
265 
266 /**
267   * @brief  Conversion half DMA transfer callback in non blocking mode for Channel2
268   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
269   *         the configuration information for the specified DAC.
270   * @retval None
271   */
HAL_DACEx_ConvHalfCpltCallbackCh2(DAC_HandleTypeDef * hdac)272 __weak void HAL_DACEx_ConvHalfCpltCallbackCh2(DAC_HandleTypeDef* hdac)
273 {
274   /* Prevent unused argument(s) compilation warning */
275   UNUSED(hdac);
276 
277   /* NOTE : This function should not be modified, when the callback is needed,
278             the HAL_DACEx_ConvHalfCpltCallbackCh2 could be implemented in the user file
279    */
280 }
281 
282 /**
283   * @brief  Error DAC callback for Channel2.
284   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
285   *         the configuration information for the specified DAC.
286   * @retval None
287   */
HAL_DACEx_ErrorCallbackCh2(DAC_HandleTypeDef * hdac)288 __weak void HAL_DACEx_ErrorCallbackCh2(DAC_HandleTypeDef *hdac)
289 {
290   /* Prevent unused argument(s) compilation warning */
291   UNUSED(hdac);
292 
293   /* NOTE : This function should not be modified, when the callback is needed,
294             the HAL_DACEx_ErrorCallbackCh2 could be implemented in the user file
295    */
296 }
297 
298 /**
299   * @brief  DMA underrun DAC callback for Channel2.
300   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
301   *         the configuration information for the specified DAC.
302   * @retval None
303   */
HAL_DACEx_DMAUnderrunCallbackCh2(DAC_HandleTypeDef * hdac)304 __weak void HAL_DACEx_DMAUnderrunCallbackCh2(DAC_HandleTypeDef *hdac)
305 {
306   /* Prevent unused argument(s) compilation warning */
307   UNUSED(hdac);
308 
309   /* NOTE : This function should not be modified, when the callback is needed,
310             the HAL_DAC_DMAUnderrunCallbackCh2 could be implemented in the user file
311    */
312 }
313 
314 /**
315   * @brief  Enables DAC and starts conversion of channel.
316   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
317   *         the configuration information for the specified DAC.
318   * @param  Channel The selected DAC channel.
319   *          This parameter can be one of the following values:
320   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
321   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
322   * @retval HAL status
323   */
HAL_DAC_Start(DAC_HandleTypeDef * hdac,uint32_t Channel)324 HAL_StatusTypeDef HAL_DAC_Start(DAC_HandleTypeDef* hdac, uint32_t Channel)
325 {
326   uint32_t tmp1 = 0U, tmp2 = 0U;
327 
328   /* Check the parameters */
329   assert_param(IS_DAC_CHANNEL(Channel));
330 
331   /* Process locked */
332   __HAL_LOCK(hdac);
333 
334   /* Change DAC state */
335   hdac->State = HAL_DAC_STATE_BUSY;
336 
337   /* Enable the Peripharal */
338   __HAL_DAC_ENABLE(hdac, Channel);
339 
340   if(Channel == DAC_CHANNEL_1)
341   {
342     tmp1 = hdac->Instance->CR & DAC_CR_TEN1;
343     tmp2 = hdac->Instance->CR & DAC_CR_TSEL1;
344     /* Check if software trigger enabled */
345     if((tmp1 ==  DAC_CR_TEN1) && (tmp2 ==  DAC_CR_TSEL1))
346     {
347       /* Enable the selected DAC software conversion */
348       SET_BIT(hdac->Instance->SWTRIGR, DAC_SWTRIGR_SWTRIG1);
349     }
350   }
351   else
352   {
353     tmp1 = hdac->Instance->CR & DAC_CR_TEN2;
354     tmp2 = hdac->Instance->CR & DAC_CR_TSEL2;
355     /* Check if software trigger enabled */
356     if((tmp1 == DAC_CR_TEN2) && (tmp2 == DAC_CR_TSEL2))
357     {
358       /* Enable the selected DAC software conversion*/
359       SET_BIT(hdac->Instance->SWTRIGR, DAC_SWTRIGR_SWTRIG2);
360     }
361   }
362 
363   /* Change DAC state */
364   hdac->State = HAL_DAC_STATE_READY;
365 
366   /* Process unlocked */
367   __HAL_UNLOCK(hdac);
368 
369   /* Return function status */
370   return HAL_OK;
371 }
372 
373 /**
374   * @brief  Enables DAC and starts conversion of channel using DMA.
375   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
376   *         the configuration information for the specified DAC.
377   * @param  Channel The selected DAC channel.
378   *          This parameter can be one of the following values:
379   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
380   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
381   * @param  pData The destination peripheral Buffer address.
382   * @param  Length The length of data to be transferred from memory to DAC peripheral
383   * @param  Alignment Specifies the data alignment for DAC channel.
384   *          This parameter can be one of the following values:
385   *            @arg DAC_ALIGN_8B_R: 8bit right data alignment selected
386   *            @arg DAC_ALIGN_12B_L: 12bit left data alignment selected
387   *            @arg DAC_ALIGN_12B_R: 12bit right data alignment selected
388   * @retval HAL status
389   */
HAL_DAC_Start_DMA(DAC_HandleTypeDef * hdac,uint32_t Channel,uint32_t * pData,uint32_t Length,uint32_t Alignment)390 HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t* pData, uint32_t Length, uint32_t Alignment)
391 {
392   uint32_t tmpreg = 0U;
393 
394   /* Check the parameters */
395   assert_param(IS_DAC_CHANNEL(Channel));
396   assert_param(IS_DAC_ALIGN(Alignment));
397 
398   /* Process locked */
399   __HAL_LOCK(hdac);
400 
401   /* Change DAC state */
402   hdac->State = HAL_DAC_STATE_BUSY;
403 
404   if(Channel == DAC_CHANNEL_1)
405   {
406     /* Set the DMA transfer complete callback for channel1 */
407     hdac->DMA_Handle1->XferCpltCallback = DAC_DMAConvCpltCh1;
408 
409     /* Set the DMA half transfer complete callback for channel1 */
410     hdac->DMA_Handle1->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh1;
411 
412     /* Set the DMA error callback for channel1 */
413     hdac->DMA_Handle1->XferErrorCallback = DAC_DMAErrorCh1;
414 
415     /* Enable the selected DAC channel1 DMA request */
416     SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN1);
417 
418     /* Case of use of channel 1 */
419     switch(Alignment)
420     {
421       case DAC_ALIGN_12B_R:
422         /* Get DHR12R1 address */
423         tmpreg = (uint32_t)&hdac->Instance->DHR12R1;
424         break;
425       case DAC_ALIGN_12B_L:
426         /* Get DHR12L1 address */
427         tmpreg = (uint32_t)&hdac->Instance->DHR12L1;
428         break;
429       case DAC_ALIGN_8B_R:
430         /* Get DHR8R1 address */
431         tmpreg = (uint32_t)&hdac->Instance->DHR8R1;
432         break;
433       default:
434         break;
435     }
436     UNUSED(tmpreg);		/* avoid warning on tmpreg affectation with stupid compiler */
437   }
438   else
439   {
440     /* Set the DMA transfer complete callback for channel2 */
441     hdac->DMA_Handle2->XferCpltCallback = DAC_DMAConvCpltCh2;
442 
443     /* Set the DMA half transfer complete callback for channel2 */
444     hdac->DMA_Handle2->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh2;
445 
446     /* Set the DMA error callback for channel2 */
447     hdac->DMA_Handle2->XferErrorCallback = DAC_DMAErrorCh2;
448 
449     /* Enable the selected DAC channel2 DMA request */
450     SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN2);
451 
452     /* Case of use of channel 2 */
453     switch(Alignment)
454     {
455       case DAC_ALIGN_12B_R:
456         /* Get DHR12R2 address */
457         tmpreg = (uint32_t)&hdac->Instance->DHR12R2;
458         break;
459       case DAC_ALIGN_12B_L:
460         /* Get DHR12L2 address */
461         tmpreg = (uint32_t)&hdac->Instance->DHR12L2;
462         break;
463       case DAC_ALIGN_8B_R:
464         /* Get DHR8R2 address */
465         tmpreg = (uint32_t)&hdac->Instance->DHR8R2;
466         break;
467       default:
468         break;
469     }
470   }
471 
472   /* Enable the DMA Stream */
473   if(Channel == DAC_CHANNEL_1)
474   {
475     /* Enable the DAC DMA underrun interrupt */
476     __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR1);
477 
478     /* Enable the DMA Stream */
479     HAL_DMA_Start_IT(hdac->DMA_Handle1, (uint32_t)pData, tmpreg, Length);
480   }
481   else
482   {
483     /* Enable the DAC DMA underrun interrupt */
484     __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR2);
485 
486     /* Enable the DMA Stream */
487     HAL_DMA_Start_IT(hdac->DMA_Handle2, (uint32_t)pData, tmpreg, Length);
488   }
489 
490   /* Enable the Peripharal */
491   __HAL_DAC_ENABLE(hdac, Channel);
492 
493   /* Process Unlocked */
494   __HAL_UNLOCK(hdac);
495 
496   /* Return function status */
497   return HAL_OK;
498 }
499 
500 /**
501   * @brief  Disables DAC and stop conversion of channel.
502   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
503   *         the configuration information for the specified DAC.
504   * @param  Channel The selected DAC channel.
505   *          This parameter can be one of the following values:
506   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
507   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
508   * @retval HAL status
509   */
HAL_DAC_Stop_DMA(DAC_HandleTypeDef * hdac,uint32_t Channel)510 HAL_StatusTypeDef HAL_DAC_Stop_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel)
511 {
512   HAL_StatusTypeDef status = HAL_OK;
513 
514   /* Check the parameters */
515   assert_param(IS_DAC_CHANNEL(Channel));
516 
517   /* Disable the selected DAC channel DMA request */
518   CLEAR_BIT(hdac->Instance->CR, (DAC_CR_DMAEN1 << Channel));
519 
520   /* Disable the Peripharal */
521   __HAL_DAC_DISABLE(hdac, Channel);
522 
523   /* Disable the DMA Channel */
524   /* Channel1 is used */
525   if(Channel == DAC_CHANNEL_1)
526   {
527     status = HAL_DMA_Abort(hdac->DMA_Handle1);
528   }
529   else /* Channel2 is used for */
530   {
531     status = HAL_DMA_Abort(hdac->DMA_Handle2);
532   }
533 
534   /* Check if DMA Channel effectively disabled */
535   if(status != HAL_OK)
536   {
537     /* Update DAC state machine to error */
538     hdac->State = HAL_DAC_STATE_ERROR;
539   }
540   else
541   {
542     /* Change DAC state */
543     hdac->State = HAL_DAC_STATE_READY;
544   }
545 
546   /* Return function status */
547   return status;
548 }
549 
550 /**
551   * @brief  Returns the last data output value of the selected DAC channel.
552   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
553   *         the configuration information for the specified DAC.
554   * @param  Channel The selected DAC channel.
555   *          This parameter can be one of the following values:
556   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
557   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
558   * @retval The selected DAC channel data output value.
559   */
HAL_DAC_GetValue(DAC_HandleTypeDef * hdac,uint32_t Channel)560 uint32_t HAL_DAC_GetValue(DAC_HandleTypeDef* hdac, uint32_t Channel)
561 {
562   /* Check the parameters */
563   assert_param(IS_DAC_CHANNEL(Channel));
564 
565   /* Returns the DAC channel data output register value */
566   if(Channel == DAC_CHANNEL_1)
567   {
568     return hdac->Instance->DOR1;
569   }
570   else
571   {
572     return hdac->Instance->DOR2;
573   }
574 }
575 
576 /**
577   * @brief  Handles DAC interrupt request
578   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
579   *         the configuration information for the specified DAC.
580   * @retval None
581   */
HAL_DAC_IRQHandler(DAC_HandleTypeDef * hdac)582 void HAL_DAC_IRQHandler(DAC_HandleTypeDef* hdac)
583 {
584   /* Check underrun flag of DAC channel 1 */
585   if(__HAL_DAC_GET_FLAG(hdac, DAC_FLAG_DMAUDR1))
586   {
587     /* Change DAC state to error state */
588     hdac->State = HAL_DAC_STATE_ERROR;
589 
590     /* Set DAC error code to chanel1 DMA underrun error */
591     hdac->ErrorCode |= HAL_DAC_ERROR_DMAUNDERRUNCH1;
592 
593     /* Clear the underrun flag */
594     __HAL_DAC_CLEAR_FLAG(hdac,DAC_FLAG_DMAUDR1);
595 
596     /* Disable the selected DAC channel1 DMA request */
597     CLEAR_BIT(hdac->Instance->CR, DAC_CR_DMAEN1);
598 
599     /* Error callback */
600 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
601       hdac->DMAUnderrunCallbackCh1(hdac);
602 #else
603     HAL_DAC_DMAUnderrunCallbackCh1(hdac);
604 #endif
605   }
606 
607   /* Check underrun flag of DAC channel 2 */
608   if(__HAL_DAC_GET_FLAG(hdac, DAC_FLAG_DMAUDR2))
609   {
610     /* Change DAC state to error state */
611     hdac->State = HAL_DAC_STATE_ERROR;
612 
613     /* Set DAC error code to channel2 DMA underrun error */
614     hdac->ErrorCode |= HAL_DAC_ERROR_DMAUNDERRUNCH2;
615 
616     /* Clear the underrun flag */
617     __HAL_DAC_CLEAR_FLAG(hdac,DAC_FLAG_DMAUDR2);
618 
619     /* Disable the selected DAC channel1 DMA request */
620     CLEAR_BIT(hdac->Instance->CR, DAC_CR_DMAEN2);
621 
622     /* Error callback */
623 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
624       hdac->DMAUnderrunCallbackCh2(hdac);
625 #else
626     HAL_DACEx_DMAUnderrunCallbackCh2(hdac);
627 #endif
628   }
629 }
630 
631 
632 /**
633   * @brief  Set the specified data holding register value for DAC channel.
634   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
635   *         the configuration information for the specified DAC.
636   * @param  Channel The selected DAC channel.
637   *          This parameter can be one of the following values:
638   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
639   *            @arg DAC_CHANNEL_2: DAC Channel2 selected
640   * @param  Alignment Specifies the data alignment.
641   *          This parameter can be one of the following values:
642   *            @arg DAC_ALIGN_8B_R: 8bit right data alignment selected
643   *            @arg DAC_ALIGN_12B_L: 12bit left data alignment selected
644   *            @arg DAC_ALIGN_12B_R: 12bit right data alignment selected
645   * @param  Data Data to be loaded in the selected data holding register.
646   * @retval HAL status
647   */
HAL_DAC_SetValue(DAC_HandleTypeDef * hdac,uint32_t Channel,uint32_t Alignment,uint32_t Data)648 HAL_StatusTypeDef HAL_DAC_SetValue(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data)
649 {
650   __IO uint32_t tmp = 0U;
651 
652   /* Check the parameters */
653   assert_param(IS_DAC_CHANNEL(Channel));
654   assert_param(IS_DAC_ALIGN(Alignment));
655   assert_param(IS_DAC_DATA(Data));
656 
657   tmp = (uint32_t)hdac->Instance;
658   if(Channel == DAC_CHANNEL_1)
659   {
660     tmp += DAC_DHR12R1_ALIGNMENT(Alignment);
661   }
662   else
663   {
664     tmp += DAC_DHR12R2_ALIGNMENT(Alignment);
665   }
666 
667   /* Set the DAC channel selected data holding register */
668   *(__IO uint32_t *) tmp = Data;
669 
670   /* Return function status */
671   return HAL_OK;
672 }
673 #else /* All products with only one channel */
674 
675 /**
676   * @brief  Enables DAC and starts conversion of channel.
677   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
678   *         the configuration information for the specified DAC.
679   * @param  Channel The selected DAC channel.
680   *          This parameter can be one of the following values:
681   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
682   * @retval HAL status
683   */
HAL_DAC_Start(DAC_HandleTypeDef * hdac,uint32_t Channel)684 HAL_StatusTypeDef HAL_DAC_Start(DAC_HandleTypeDef* hdac, uint32_t Channel)
685 {
686   uint32_t tmp1 = 0U, tmp2 = 0U;
687 
688   /* Check the parameters */
689   assert_param(IS_DAC_CHANNEL(Channel));
690 
691   /* Process locked */
692   __HAL_LOCK(hdac);
693 
694   /* Change DAC state */
695   hdac->State = HAL_DAC_STATE_BUSY;
696 
697   /* Enable the Peripharal */
698   __HAL_DAC_ENABLE(hdac, Channel);
699 
700   tmp1 = hdac->Instance->CR & DAC_CR_TEN1;
701   tmp2 = hdac->Instance->CR & DAC_CR_TSEL1;
702   /* Check if software trigger enabled */
703   if((tmp1 ==  DAC_CR_TEN1) && (tmp2 ==  DAC_CR_TSEL1))
704   {
705     /* Enable the selected DAC software conversion */
706     SET_BIT(hdac->Instance->SWTRIGR, DAC_SWTRIGR_SWTRIG1);
707   }
708 
709   /* Change DAC state */
710   hdac->State = HAL_DAC_STATE_READY;
711 
712   /* Process unlocked */
713   __HAL_UNLOCK(hdac);
714 
715   /* Return function status */
716   return HAL_OK;
717 }
718 
719 /**
720   * @brief  Enables DAC and starts conversion of channel using DMA.
721   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
722   *         the configuration information for the specified DAC.
723   * @param  Channel The selected DAC channel.
724   *          This parameter can be one of the following values:
725   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
726   * @param  pData The destination peripheral Buffer address.
727   * @param  Length The length of data to be transferred from memory to DAC peripheral
728   * @param  Alignment Specifies the data alignment for DAC channel.
729   *          This parameter can be one of the following values:
730   *            @arg DAC_ALIGN_8B_R: 8bit right data alignment selected
731   *            @arg DAC_ALIGN_12B_L: 12bit left data alignment selected
732   *            @arg DAC_ALIGN_12B_R: 12bit right data alignment selected
733   * @retval HAL status
734   */
HAL_DAC_Start_DMA(DAC_HandleTypeDef * hdac,uint32_t Channel,uint32_t * pData,uint32_t Length,uint32_t Alignment)735 HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t* pData, uint32_t Length, uint32_t Alignment)
736 {
737   uint32_t tmpreg = 0U;
738 
739   /* Check the parameters */
740   assert_param(IS_DAC_CHANNEL(Channel));
741   assert_param(IS_DAC_ALIGN(Alignment));
742 
743   /* Process locked */
744   __HAL_LOCK(hdac);
745 
746   /* Change DAC state */
747   hdac->State = HAL_DAC_STATE_BUSY;
748 
749   /* Set the DMA transfer complete callback for channel1 */
750   hdac->DMA_Handle1->XferCpltCallback = DAC_DMAConvCpltCh1;
751 
752   /* Set the DMA half transfer complete callback for channel1 */
753   hdac->DMA_Handle1->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh1;
754 
755   /* Set the DMA error callback for channel1 */
756   hdac->DMA_Handle1->XferErrorCallback = DAC_DMAErrorCh1;
757 
758   /* Enable the selected DAC channel1 DMA request */
759   SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN1);
760 
761   /* Case of use of channel 1 */
762   switch(Alignment)
763   {
764     case DAC_ALIGN_12B_R:
765       /* Get DHR12R1 address */
766       tmpreg = (uint32_t)&hdac->Instance->DHR12R1;
767       break;
768     case DAC_ALIGN_12B_L:
769       /* Get DHR12L1 address */
770       tmpreg = (uint32_t)&hdac->Instance->DHR12L1;
771       break;
772     case DAC_ALIGN_8B_R:
773       /* Get DHR8R1 address */
774       tmpreg = (uint32_t)&hdac->Instance->DHR8R1;
775       break;
776     default:
777       break;
778   }
779   UNUSED(tmpreg);		/* avoid warning on tmpreg affectation with stupid compiler */
780 
781   /* Enable the DMA Stream */
782   /* Enable the DAC DMA underrun interrupt */
783   __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR1);
784 
785   /* Enable the DMA Stream */
786   HAL_DMA_Start_IT(hdac->DMA_Handle1, (uint32_t)pData, tmpreg, Length);
787 
788   /* Enable the Peripharal */
789   __HAL_DAC_ENABLE(hdac, Channel);
790 
791   /* Process Unlocked */
792   __HAL_UNLOCK(hdac);
793 
794   /* Return function status */
795   return HAL_OK;
796 }
797 
798 /**
799   * @brief  Disables DAC and stop conversion of channel.
800   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
801   *         the configuration information for the specified DAC.
802   * @param  Channel The selected DAC channel.
803   *          This parameter can be one of the following values:
804   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
805   * @retval HAL status
806   */
HAL_DAC_Stop_DMA(DAC_HandleTypeDef * hdac,uint32_t Channel)807 HAL_StatusTypeDef HAL_DAC_Stop_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel)
808 {
809   HAL_StatusTypeDef status = HAL_OK;
810 
811   /* Check the parameters */
812   assert_param(IS_DAC_CHANNEL(Channel));
813 
814   /* Disable the selected DAC channel DMA request */
815   CLEAR_BIT(hdac->Instance->CR, (DAC_CR_DMAEN1 << Channel));
816 
817   /* Disable the Peripharal */
818   __HAL_DAC_DISABLE(hdac, Channel);
819 
820   /* Disable the DMA Channel */
821   status = HAL_DMA_Abort(hdac->DMA_Handle1);
822 
823   /* Check if DMA Channel effectively disabled */
824   if(status != HAL_OK)
825   {
826     /* Update DAC state machine to error */
827     hdac->State = HAL_DAC_STATE_ERROR;
828   }
829   else
830   {
831     /* Change DAC state */
832     hdac->State = HAL_DAC_STATE_READY;
833   }
834 
835   /* Return function status */
836   return status;
837 }
838 
839 /**
840   * @brief  Returns the last data output value of the selected DAC channel.
841   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
842   *         the configuration information for the specified DAC.
843   * @param  Channel The selected DAC channel.
844   *          This parameter can be one of the following values:
845   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
846   * @retval The selected DAC channel data output value.
847   */
HAL_DAC_GetValue(DAC_HandleTypeDef * hdac,uint32_t Channel)848 uint32_t HAL_DAC_GetValue(DAC_HandleTypeDef* hdac, uint32_t Channel)
849 {
850   /* Check the parameters */
851   assert_param(IS_DAC_CHANNEL(Channel));
852 
853   /* Returns the DAC channel data output register value */
854   return hdac->Instance->DOR1;
855 }
856 
857 /**
858   * @brief  Handles DAC interrupt request
859   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
860   *         the configuration information for the specified DAC.
861   * @retval None
862   */
HAL_DAC_IRQHandler(DAC_HandleTypeDef * hdac)863 void HAL_DAC_IRQHandler(DAC_HandleTypeDef* hdac)
864 {
865   /* Check underrun flag of DAC channel 1 */
866   if(__HAL_DAC_GET_FLAG(hdac, DAC_FLAG_DMAUDR1))
867   {
868     /* Change DAC state to error state */
869     hdac->State = HAL_DAC_STATE_ERROR;
870 
871     /* Set DAC error code to chanel1 DMA underrun error */
872     hdac->ErrorCode |= HAL_DAC_ERROR_DMAUNDERRUNCH1;
873 
874     /* Clear the underrun flag */
875     __HAL_DAC_CLEAR_FLAG(hdac,DAC_FLAG_DMAUDR1);
876 
877     /* Disable the selected DAC channel1 DMA request */
878     CLEAR_BIT(hdac->Instance->CR, DAC_CR_DMAEN1);
879 
880     /* Error callback */
881     HAL_DAC_DMAUnderrunCallbackCh1(hdac);
882   }
883 }
884 
885 /**
886   * @brief  Set the specified data holding register value for DAC channel.
887   * @param  hdac pointer to a DAC_HandleTypeDef structure that contains
888   *         the configuration information for the specified DAC.
889   * @param  Channel The selected DAC channel.
890   *          This parameter can be one of the following values:
891   *            @arg DAC_CHANNEL_1: DAC Channel1 selected
892   * @param  Alignment Specifies the data alignment.
893   *          This parameter can be one of the following values:
894   *            @arg DAC_ALIGN_8B_R: 8bit right data alignment selected
895   *            @arg DAC_ALIGN_12B_L: 12bit left data alignment selected
896   *            @arg DAC_ALIGN_12B_R: 12bit right data alignment selected
897   * @param  Data Data to be loaded in the selected data holding register.
898   * @retval HAL status
899   */
HAL_DAC_SetValue(DAC_HandleTypeDef * hdac,uint32_t Channel,uint32_t Alignment,uint32_t Data)900 HAL_StatusTypeDef HAL_DAC_SetValue(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data)
901 {
902   __IO uint32_t tmp = 0U;
903 
904   /* Check the parameters */
905   assert_param(IS_DAC_CHANNEL(Channel));
906   assert_param(IS_DAC_ALIGN(Alignment));
907   assert_param(IS_DAC_DATA(Data));
908 
909   tmp = (uint32_t)hdac->Instance;
910   tmp += DAC_DHR12R1_ALIGNMENT(Alignment);
911 
912   /* Set the DAC channel selected data holding register */
913   *(__IO uint32_t *) tmp = Data;
914 
915   /* Return function status */
916   return HAL_OK;
917 }
918 
919 #endif  /* #if defined (STM32L072xx) || defined (STM32L073xx) || defined (STM32L082xx) || defined (STM32L083xx) */
920 
921 /**
922   * @}
923   */
924 
925 /**
926   * @}
927   */
928 
929 /** @addtogroup DACEx_Private
930   * @{
931   */
932 #if defined (STM32L072xx) || defined (STM32L073xx) || defined (STM32L082xx) || defined (STM32L083xx)
933 /**
934   * @brief  DMA conversion complete callback.
935   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
936   *                the configuration information for the specified DMA module.
937   * @retval None
938   */
DAC_DMAConvCpltCh2(DMA_HandleTypeDef * hdma)939 static void DAC_DMAConvCpltCh2(DMA_HandleTypeDef *hdma)
940 {
941   DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
942 
943   HAL_DACEx_ConvCpltCallbackCh2(hdac);
944 
945   hdac->State= HAL_DAC_STATE_READY;
946 }
947 
948 /**
949   * @brief  DMA half transfer complete callback.
950   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
951   *                the configuration information for the specified DMA module.
952   * @retval None
953   */
DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef * hdma)954 static void DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef *hdma)
955 {
956     DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
957     /* Conversion complete callback */
958     HAL_DACEx_ConvHalfCpltCallbackCh2(hdac);
959 }
960 
961 /**
962   * @brief  DMA error callback
963   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
964   *                the configuration information for the specified DMA module.
965   * @retval None
966   */
DAC_DMAErrorCh2(DMA_HandleTypeDef * hdma)967 static void DAC_DMAErrorCh2(DMA_HandleTypeDef *hdma)
968 {
969   DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
970 
971   /* Set DAC error code to DMA error */
972   hdac->ErrorCode |= HAL_DAC_ERROR_DMA;
973 
974   HAL_DACEx_ErrorCallbackCh2(hdac);
975 
976   hdac->State= HAL_DAC_STATE_READY;
977 }
978 #endif /* STM32L072xx || STM32L073xx || STM32L082xx || STM32L083xx */
979 
980 /**
981   * @brief  DMA conversion complete callback.
982   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
983   *                the configuration information for the specified DMA module.
984   * @retval None
985   */
DAC_DMAConvCpltCh1(DMA_HandleTypeDef * hdma)986 static void DAC_DMAConvCpltCh1(DMA_HandleTypeDef *hdma)
987 {
988   DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
989 
990 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
991   hdac->ConvCpltCallbackCh1(hdac);
992 #else
993   HAL_DAC_ConvCpltCallbackCh1(hdac);
994 #endif
995 
996   hdac->State= HAL_DAC_STATE_READY;
997 }
998 
999 /**
1000   * @brief  DMA half transfer complete callback.
1001   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1002   *                the configuration information for the specified DMA module.
1003   * @retval None
1004   */
DAC_DMAHalfConvCpltCh1(DMA_HandleTypeDef * hdma)1005 static void DAC_DMAHalfConvCpltCh1(DMA_HandleTypeDef *hdma)
1006 {
1007   DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1008 
1009   /* Conversion complete callback */
1010 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
1011   hdac->ConvHalfCpltCallbackCh1(hdac);
1012 #else
1013   HAL_DAC_ConvHalfCpltCallbackCh1(hdac);
1014 #endif
1015 }
1016 
1017 /**
1018   * @brief  DMA error callback
1019   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
1020   *                the configuration information for the specified DMA module.
1021   * @retval None
1022   */
DAC_DMAErrorCh1(DMA_HandleTypeDef * hdma)1023 static void DAC_DMAErrorCh1(DMA_HandleTypeDef *hdma)
1024 {
1025   DAC_HandleTypeDef* hdac = ( DAC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1026 
1027   /* Set DAC error code to DMA error */
1028   hdac->ErrorCode |= HAL_DAC_ERROR_DMA;
1029 
1030   HAL_DAC_ErrorCallbackCh1(hdac);
1031 
1032   hdac->State= HAL_DAC_STATE_READY;
1033 }
1034 
1035 /**
1036   * @}
1037   */
1038 
1039 /**
1040   * @}
1041   */
1042 
1043 /**
1044   * @}
1045   */
1046 #endif /* HAL_DAC_MODULE_ENABLED */
1047 #endif /* #if !defined (STM32L010xB) && !defined (STM32L010x8) && !defined (STM32L010x6) && !defined (STM32L010x4) && !defined (STM32L011xx) && !defined (STM32L021xx) && !defined (STM32L031xx) && !defined (STM32L041xx) && !defined (STM32L051xx) && !defined (STM32L071xx) && !defined (STM32L081xx) */
1048 
1049