1 /**
2 ******************************************************************************
3 * @file stm32l1xx_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) 2016 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 @endverbatim
33 ******************************************************************************
34 */
35
36
37 /* Includes ------------------------------------------------------------------*/
38 #include "stm32l1xx_hal.h"
39
40 /** @addtogroup STM32L1xx_HAL_Driver
41 * @{
42 */
43
44 #ifdef HAL_DAC_MODULE_ENABLED
45
46 #if defined(DAC1)
47
48 /** @defgroup DACEx DACEx
49 * @brief DAC Extended HAL module driver
50 * @{
51 */
52
53 /* Private typedef -----------------------------------------------------------*/
54 /* Private define ------------------------------------------------------------*/
55
56 /* Private macro -------------------------------------------------------------*/
57 /* Private variables ---------------------------------------------------------*/
58 /* Private function prototypes -----------------------------------------------*/
59 /* Exported functions --------------------------------------------------------*/
60
61 /** @defgroup DACEx_Exported_Functions DACEx Exported Functions
62 * @{
63 */
64
65 /** @defgroup DACEx_Exported_Functions_Group2 IO operation functions
66 * @brief Extended IO operation functions
67 *
68 @verbatim
69 ==============================================================================
70 ##### Extended features functions #####
71 ==============================================================================
72 [..] This section provides functions allowing to:
73 (+) Start conversion.
74 (+) Stop conversion.
75 (+) Start conversion and enable DMA transfer.
76 (+) Stop conversion and disable DMA transfer.
77 (+) Get result of conversion.
78 (+) Get result of dual mode conversion.
79
80 @endverbatim
81 * @{
82 */
83
84
85 /**
86 * @brief Enables DAC and starts conversion of both channels.
87 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
88 * the configuration information for the specified DAC.
89 * @retval HAL status
90 */
HAL_DACEx_DualStart(DAC_HandleTypeDef * hdac)91 HAL_StatusTypeDef HAL_DACEx_DualStart(DAC_HandleTypeDef *hdac)
92 {
93 uint32_t tmp_swtrig = 0UL;
94
95 /* Check the DAC peripheral handle */
96 if (hdac == NULL)
97 {
98 return HAL_ERROR;
99 }
100
101
102 /* Process locked */
103 __HAL_LOCK(hdac);
104
105 /* Change DAC state */
106 hdac->State = HAL_DAC_STATE_BUSY;
107
108 /* Enable the Peripheral */
109 __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_1);
110 __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_2);
111
112 /* Check if software trigger enabled */
113 if ((hdac->Instance->CR & (DAC_CR_TEN1 | DAC_CR_TSEL1)) == DAC_TRIGGER_SOFTWARE)
114 {
115 tmp_swtrig |= DAC_SWTRIGR_SWTRIG1;
116 }
117 if ((hdac->Instance->CR & (DAC_CR_TEN2 | DAC_CR_TSEL2)) == (DAC_TRIGGER_SOFTWARE << (DAC_CHANNEL_2 & 0x10UL)))
118 {
119 tmp_swtrig |= DAC_SWTRIGR_SWTRIG2;
120 }
121 /* Enable the selected DAC software conversion*/
122 SET_BIT(hdac->Instance->SWTRIGR, tmp_swtrig);
123
124 /* Change DAC state */
125 hdac->State = HAL_DAC_STATE_READY;
126
127 /* Process unlocked */
128 __HAL_UNLOCK(hdac);
129
130 /* Return function status */
131 return HAL_OK;
132 }
133
134 /**
135 * @brief Disables DAC and stop conversion of both channels.
136 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
137 * the configuration information for the specified DAC.
138 * @retval HAL status
139 */
HAL_DACEx_DualStop(DAC_HandleTypeDef * hdac)140 HAL_StatusTypeDef HAL_DACEx_DualStop(DAC_HandleTypeDef *hdac)
141 {
142 /* Check the DAC peripheral handle */
143 if (hdac == NULL)
144 {
145 return HAL_ERROR;
146 }
147
148
149 /* Disable the Peripheral */
150 __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_1);
151 __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_2);
152
153 /* Change DAC state */
154 hdac->State = HAL_DAC_STATE_READY;
155
156 /* Return function status */
157 return HAL_OK;
158 }
159
160
161 /**
162 * @brief Enable or disable the selected DAC channel wave generation.
163 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
164 * the configuration information for the specified DAC.
165 * @param Channel The selected DAC channel.
166 * This parameter can be one of the following values:
167 * @arg DAC_CHANNEL_1: DAC Channel1 selected
168 * @arg DAC_CHANNEL_2: DAC Channel2 selected
169 * @param Amplitude Select max triangle amplitude.
170 * This parameter can be one of the following values:
171 * @arg DAC_TRIANGLEAMPLITUDE_1: Select max triangle amplitude of 1
172 * @arg DAC_TRIANGLEAMPLITUDE_3: Select max triangle amplitude of 3
173 * @arg DAC_TRIANGLEAMPLITUDE_7: Select max triangle amplitude of 7
174 * @arg DAC_TRIANGLEAMPLITUDE_15: Select max triangle amplitude of 15
175 * @arg DAC_TRIANGLEAMPLITUDE_31: Select max triangle amplitude of 31
176 * @arg DAC_TRIANGLEAMPLITUDE_63: Select max triangle amplitude of 63
177 * @arg DAC_TRIANGLEAMPLITUDE_127: Select max triangle amplitude of 127
178 * @arg DAC_TRIANGLEAMPLITUDE_255: Select max triangle amplitude of 255
179 * @arg DAC_TRIANGLEAMPLITUDE_511: Select max triangle amplitude of 511
180 * @arg DAC_TRIANGLEAMPLITUDE_1023: Select max triangle amplitude of 1023
181 * @arg DAC_TRIANGLEAMPLITUDE_2047: Select max triangle amplitude of 2047
182 * @arg DAC_TRIANGLEAMPLITUDE_4095: Select max triangle amplitude of 4095
183 * @retval HAL status
184 */
HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef * hdac,uint32_t Channel,uint32_t Amplitude)185 HAL_StatusTypeDef HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Amplitude)
186 {
187 /* Check the DAC peripheral handle */
188 if (hdac == NULL)
189 {
190 return HAL_ERROR;
191 }
192
193 /* Check the parameters */
194 assert_param(IS_DAC_CHANNEL(Channel));
195 assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude));
196
197 /* Process locked */
198 __HAL_LOCK(hdac);
199
200 /* Change DAC state */
201 hdac->State = HAL_DAC_STATE_BUSY;
202
203 /* Enable the triangle wave generation for the selected DAC channel */
204 MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1) | (DAC_CR_MAMP1)) << (Channel & 0x10UL),
205 (DAC_CR_WAVE1_1 | Amplitude) << (Channel & 0x10UL));
206
207 /* Change DAC state */
208 hdac->State = HAL_DAC_STATE_READY;
209
210 /* Process unlocked */
211 __HAL_UNLOCK(hdac);
212
213 /* Return function status */
214 return HAL_OK;
215 }
216
217 /**
218 * @brief Enable or disable the selected DAC channel wave generation.
219 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
220 * the configuration information for the specified DAC.
221 * @param Channel The selected DAC channel.
222 * This parameter can be one of the following values:
223 * @arg DAC_CHANNEL_1: DAC Channel1 selected
224 * @arg DAC_CHANNEL_2: DAC Channel2 selected
225 * @param Amplitude Unmask DAC channel LFSR for noise wave generation.
226 * This parameter can be one of the following values:
227 * @arg DAC_LFSRUNMASK_BIT0: Unmask DAC channel LFSR bit0 for noise wave generation
228 * @arg DAC_LFSRUNMASK_BITS1_0: Unmask DAC channel LFSR bit[1:0] for noise wave generation
229 * @arg DAC_LFSRUNMASK_BITS2_0: Unmask DAC channel LFSR bit[2:0] for noise wave generation
230 * @arg DAC_LFSRUNMASK_BITS3_0: Unmask DAC channel LFSR bit[3:0] for noise wave generation
231 * @arg DAC_LFSRUNMASK_BITS4_0: Unmask DAC channel LFSR bit[4:0] for noise wave generation
232 * @arg DAC_LFSRUNMASK_BITS5_0: Unmask DAC channel LFSR bit[5:0] for noise wave generation
233 * @arg DAC_LFSRUNMASK_BITS6_0: Unmask DAC channel LFSR bit[6:0] for noise wave generation
234 * @arg DAC_LFSRUNMASK_BITS7_0: Unmask DAC channel LFSR bit[7:0] for noise wave generation
235 * @arg DAC_LFSRUNMASK_BITS8_0: Unmask DAC channel LFSR bit[8:0] for noise wave generation
236 * @arg DAC_LFSRUNMASK_BITS9_0: Unmask DAC channel LFSR bit[9:0] for noise wave generation
237 * @arg DAC_LFSRUNMASK_BITS10_0: Unmask DAC channel LFSR bit[10:0] for noise wave generation
238 * @arg DAC_LFSRUNMASK_BITS11_0: Unmask DAC channel LFSR bit[11:0] for noise wave generation
239 * @retval HAL status
240 */
HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef * hdac,uint32_t Channel,uint32_t Amplitude)241 HAL_StatusTypeDef HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Amplitude)
242 {
243 /* Check the DAC peripheral handle */
244 if (hdac == NULL)
245 {
246 return HAL_ERROR;
247 }
248
249 /* Check the parameters */
250 assert_param(IS_DAC_CHANNEL(Channel));
251 assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude));
252
253 /* Process locked */
254 __HAL_LOCK(hdac);
255
256 /* Change DAC state */
257 hdac->State = HAL_DAC_STATE_BUSY;
258
259 /* Enable the noise wave generation for the selected DAC channel */
260 MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1) | (DAC_CR_MAMP1)) << (Channel & 0x10UL),
261 (DAC_CR_WAVE1_0 | Amplitude) << (Channel & 0x10UL));
262
263 /* Change DAC state */
264 hdac->State = HAL_DAC_STATE_READY;
265
266 /* Process unlocked */
267 __HAL_UNLOCK(hdac);
268
269 /* Return function status */
270 return HAL_OK;
271 }
272
273
274 /**
275 * @brief Set the specified data holding register value for dual DAC channel.
276 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
277 * the configuration information for the specified DAC.
278 * @param Alignment Specifies the data alignment for dual channel DAC.
279 * This parameter can be one of the following values:
280 * DAC_ALIGN_8B_R: 8bit right data alignment selected
281 * DAC_ALIGN_12B_L: 12bit left data alignment selected
282 * DAC_ALIGN_12B_R: 12bit right data alignment selected
283 * @param Data1 Data for DAC Channel1 to be loaded in the selected data holding register.
284 * @param Data2 Data for DAC Channel2 to be loaded in the selected data holding register.
285 * @note In dual mode, a unique register access is required to write in both
286 * DAC channels at the same time.
287 * @retval HAL status
288 */
HAL_DACEx_DualSetValue(DAC_HandleTypeDef * hdac,uint32_t Alignment,uint32_t Data1,uint32_t Data2)289 HAL_StatusTypeDef HAL_DACEx_DualSetValue(DAC_HandleTypeDef *hdac, uint32_t Alignment, uint32_t Data1, uint32_t Data2)
290 {
291 uint32_t data;
292 uint32_t tmp;
293
294 /* Check the DAC peripheral handle */
295 if (hdac == NULL)
296 {
297 return HAL_ERROR;
298 }
299
300 /* Check the parameters */
301 assert_param(IS_DAC_ALIGN(Alignment));
302 assert_param(IS_DAC_DATA(Data1));
303 assert_param(IS_DAC_DATA(Data2));
304
305 /* Calculate and set dual DAC data holding register value */
306 if (Alignment == DAC_ALIGN_8B_R)
307 {
308 data = ((uint32_t)Data2 << 8U) | Data1;
309 }
310 else
311 {
312 data = ((uint32_t)Data2 << 16U) | Data1;
313 }
314
315 tmp = (uint32_t)hdac->Instance;
316 tmp += DAC_DHR12RD_ALIGNMENT(Alignment);
317
318 /* Set the dual DAC selected data holding register */
319 *(__IO uint32_t *)tmp = data;
320
321 /* Return function status */
322 return HAL_OK;
323 }
324
325 /**
326 * @brief Conversion complete 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_ConvCpltCallbackCh2(DAC_HandleTypeDef * hdac)331 __weak void HAL_DACEx_ConvCpltCallbackCh2(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_ConvCpltCallbackCh2 could be implemented in the user file
338 */
339 }
340
341 /**
342 * @brief Conversion half DMA transfer callback in non-blocking mode 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_ConvHalfCpltCallbackCh2(DAC_HandleTypeDef * hdac)347 __weak void HAL_DACEx_ConvHalfCpltCallbackCh2(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_ConvHalfCpltCallbackCh2 could be implemented in the user file
354 */
355 }
356
357 /**
358 * @brief Error 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_ErrorCallbackCh2(DAC_HandleTypeDef * hdac)363 __weak void HAL_DACEx_ErrorCallbackCh2(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_ErrorCallbackCh2 could be implemented in the user file
370 */
371 }
372
373 /**
374 * @brief DMA underrun DAC callback for Channel2.
375 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
376 * the configuration information for the specified DAC.
377 * @retval None
378 */
HAL_DACEx_DMAUnderrunCallbackCh2(DAC_HandleTypeDef * hdac)379 __weak void HAL_DACEx_DMAUnderrunCallbackCh2(DAC_HandleTypeDef *hdac)
380 {
381 /* Prevent unused argument(s) compilation warning */
382 UNUSED(hdac);
383
384 /* NOTE : This function should not be modified, when the callback is needed,
385 the HAL_DACEx_DMAUnderrunCallbackCh2 could be implemented in the user file
386 */
387 }
388
389
390
391 /**
392 * @}
393 */
394
395 /** @defgroup DACEx_Exported_Functions_Group3 Peripheral Control functions
396 * @brief Extended Peripheral Control functions
397 *
398 @verbatim
399 ==============================================================================
400 ##### Peripheral Control functions #####
401 ==============================================================================
402 [..] This section provides functions allowing to:
403 (+) Set the specified data holding register value for DAC channel.
404
405 @endverbatim
406 * @{
407 */
408
409
410 /**
411 * @brief Return the last data output value of the selected DAC channel.
412 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
413 * the configuration information for the specified DAC.
414 * @retval The selected DAC channel data output value.
415 */
HAL_DACEx_DualGetValue(const DAC_HandleTypeDef * hdac)416 uint32_t HAL_DACEx_DualGetValue(const DAC_HandleTypeDef *hdac)
417 {
418 uint32_t tmp = 0UL;
419
420 tmp |= hdac->Instance->DOR1;
421
422 tmp |= hdac->Instance->DOR2 << 16UL;
423
424 /* Returns the DAC channel data output register value */
425 return tmp;
426 }
427
428
429 /**
430 * @}
431 */
432 /**
433 * @}
434 */
435
436 /* Private functions ---------------------------------------------------------*/
437 /** @defgroup DACEx_Private_Functions DACEx private functions
438 * @brief Extended private functions
439 * @{
440 */
441
442
443 /**
444 * @brief DMA conversion complete callback.
445 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
446 * the configuration information for the specified DMA module.
447 * @retval None
448 */
DAC_DMAConvCpltCh2(DMA_HandleTypeDef * hdma)449 void DAC_DMAConvCpltCh2(DMA_HandleTypeDef *hdma)
450 {
451 DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
452
453 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
454 hdac->ConvCpltCallbackCh2(hdac);
455 #else
456 HAL_DACEx_ConvCpltCallbackCh2(hdac);
457 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
458
459 hdac->State = HAL_DAC_STATE_READY;
460 }
461
462 /**
463 * @brief DMA half transfer complete callback.
464 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
465 * the configuration information for the specified DMA module.
466 * @retval None
467 */
DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef * hdma)468 void DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef *hdma)
469 {
470 DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
471 /* Conversion complete callback */
472 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
473 hdac->ConvHalfCpltCallbackCh2(hdac);
474 #else
475 HAL_DACEx_ConvHalfCpltCallbackCh2(hdac);
476 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
477 }
478
479 /**
480 * @brief DMA error callback.
481 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
482 * the configuration information for the specified DMA module.
483 * @retval None
484 */
DAC_DMAErrorCh2(DMA_HandleTypeDef * hdma)485 void DAC_DMAErrorCh2(DMA_HandleTypeDef *hdma)
486 {
487 DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
488
489 /* Set DAC error code to DMA error */
490 hdac->ErrorCode |= HAL_DAC_ERROR_DMA;
491
492 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
493 hdac->ErrorCallbackCh2(hdac);
494 #else
495 HAL_DACEx_ErrorCallbackCh2(hdac);
496 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
497
498 hdac->State = HAL_DAC_STATE_READY;
499 }
500
501
502 /**
503 * @}
504 */
505
506 /**
507 * @}
508 */
509
510 #endif /* DAC1 */
511
512 #endif /* HAL_DAC_MODULE_ENABLED */
513
514 /**
515 * @}
516 */
517