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