1 /**
2 ******************************************************************************
3 * @file stm32l5xx_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) 2019 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 (+) Use HAL_DACEx_DualStart() to enable both channel and start conversion
31 for dual mode operation.
32 If software trigger is selected, using HAL_DACEx_DualStart() will start
33 the conversion of the value previously set by HAL_DACEx_DualSetValue().
34 (+) Use HAL_DACEx_DualStop() to disable both channel and stop conversion
35 for dual mode operation.
36 (+) Use HAL_DACEx_DualStart_DMA() to enable both channel and start conversion
37 for dual mode operation using DMA to feed DAC converters.
38 First issued trigger will start the conversion of the value previously
39 set by HAL_DACEx_DualSetValue().
40 The same callbacks that are used in single mode are called in dual mode to notify
41 transfer completion (half complete or complete), errors or underrun.
42 (+) Use HAL_DACEx_DualStop_DMA() to disable both channel and stop conversion
43 for dual mode operation using DMA to feed DAC converters.
44 (+) When Dual mode is enabled (i.e. DAC Channel1 and Channel2 are used simultaneously) :
45 Use HAL_DACEx_DualGetValue() to get digital data to be converted and use
46 HAL_DACEx_DualSetValue() to set digital value to converted simultaneously in
47 Channel 1 and Channel 2.
48
49 *** Signal generation operation ***
50 ===================================
51 [..]
52 (+) Use HAL_DACEx_TriangleWaveGenerate() to generate Triangle signal.
53 (+) Use HAL_DACEx_NoiseWaveGenerate() to generate Noise signal.
54
55 (+) HAL_DACEx_SelfCalibrate to calibrate one DAC channel.
56 (+) HAL_DACEx_SetUserTrimming to set user trimming value.
57 (+) HAL_DACEx_GetTrimOffset to retrieve trimming value (factory setting
58 after reset, user setting if HAL_DACEx_SetUserTrimming have been used
59 at least one time after reset).
60
61 @endverbatim
62 ******************************************************************************
63 */
64
65
66 /* Includes ------------------------------------------------------------------*/
67 #include "stm32l5xx_hal.h"
68
69 /** @addtogroup STM32L5xx_HAL_Driver
70 * @{
71 */
72
73 #ifdef HAL_DAC_MODULE_ENABLED
74
75 #if defined(DAC1)
76
77 /** @defgroup DACEx DACEx
78 * @brief DAC Extended HAL module driver
79 * @{
80 */
81
82 /* Private typedef -----------------------------------------------------------*/
83 /* Private define ------------------------------------------------------------*/
84 /* Private macro -------------------------------------------------------------*/
85 /* Private variables ---------------------------------------------------------*/
86 /* Private function prototypes -----------------------------------------------*/
87 /* Exported functions --------------------------------------------------------*/
88
89 /** @defgroup DACEx_Exported_Functions DACEx Exported Functions
90 * @{
91 */
92
93 /** @defgroup DACEx_Exported_Functions_Group2 IO operation functions
94 * @brief Extended IO operation functions
95 *
96 @verbatim
97 ==============================================================================
98 ##### Extended features functions #####
99 ==============================================================================
100 [..] This section provides functions allowing to:
101 (+) Start conversion.
102 (+) Stop conversion.
103 (+) Start conversion and enable DMA transfer.
104 (+) Stop conversion and disable DMA transfer.
105 (+) Get result of conversion.
106 (+) Get result of dual mode conversion.
107
108 @endverbatim
109 * @{
110 */
111
112
113 /**
114 * @brief Enables DAC and starts conversion of both channels.
115 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
116 * the configuration information for the specified DAC.
117 * @retval HAL status
118 */
HAL_DACEx_DualStart(DAC_HandleTypeDef * hdac)119 HAL_StatusTypeDef HAL_DACEx_DualStart(DAC_HandleTypeDef *hdac)
120 {
121 uint32_t tmp_swtrig = 0UL;
122
123
124 /* Process locked */
125 __HAL_LOCK(hdac);
126
127 /* Change DAC state */
128 hdac->State = HAL_DAC_STATE_BUSY;
129
130 /* Enable the Peripheral */
131 __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_1);
132 __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_2);
133
134 /* Check if software trigger enabled */
135 if ((hdac->Instance->CR & (DAC_CR_TEN1 | DAC_CR_TSEL1)) == DAC_TRIGGER_SOFTWARE)
136 {
137 tmp_swtrig |= DAC_SWTRIGR_SWTRIG1;
138 }
139 if ((hdac->Instance->CR & (DAC_CR_TEN2 | DAC_CR_TSEL2)) == (DAC_TRIGGER_SOFTWARE << (DAC_CHANNEL_2 & 0x10UL)))
140 {
141 tmp_swtrig |= DAC_SWTRIGR_SWTRIG2;
142 }
143 /* Enable the selected DAC software conversion*/
144 SET_BIT(hdac->Instance->SWTRIGR, tmp_swtrig);
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 Disables DAC and stop conversion of both channels.
158 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
159 * the configuration information for the specified DAC.
160 * @retval HAL status
161 */
HAL_DACEx_DualStop(DAC_HandleTypeDef * hdac)162 HAL_StatusTypeDef HAL_DACEx_DualStop(DAC_HandleTypeDef *hdac)
163 {
164
165 /* Disable the Peripheral */
166 __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_1);
167 __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_2);
168
169 /* Change DAC state */
170 hdac->State = HAL_DAC_STATE_READY;
171
172 /* Return function status */
173 return HAL_OK;
174 }
175
176 /**
177 * @brief Enables DAC and starts conversion of both channel 1 and 2 of the same DAC.
178 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
179 * the configuration information for the specified DAC.
180 * @param Channel The DAC channel that will request data from DMA.
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 pData The destination peripheral Buffer address.
185 * @param Length The length of data to be transferred from memory to DAC peripheral
186 * @param Alignment Specifies the data alignment for DAC channel.
187 * This parameter can be one of the following values:
188 * @arg DAC_ALIGN_8B_R: 8bit right data alignment selected
189 * @arg DAC_ALIGN_12B_L: 12bit left data alignment selected
190 * @arg DAC_ALIGN_12B_R: 12bit right data alignment selected
191 * @retval HAL status
192 */
HAL_DACEx_DualStart_DMA(DAC_HandleTypeDef * hdac,uint32_t Channel,uint32_t * pData,uint32_t Length,uint32_t Alignment)193 HAL_StatusTypeDef HAL_DACEx_DualStart_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t *pData, uint32_t Length,
194 uint32_t Alignment)
195 {
196 HAL_StatusTypeDef status;
197 uint32_t tmpreg = 0UL;
198
199 /* Check the parameters */
200 assert_param(IS_DAC_CHANNEL(Channel));
201 assert_param(IS_DAC_ALIGN(Alignment));
202
203 /* Process locked */
204 __HAL_LOCK(hdac);
205
206 /* Change DAC state */
207 hdac->State = HAL_DAC_STATE_BUSY;
208
209 if (Channel == DAC_CHANNEL_1)
210 {
211 /* Set the DMA transfer complete callback for channel1 */
212 hdac->DMA_Handle1->XferCpltCallback = DAC_DMAConvCpltCh1;
213
214 /* Set the DMA half transfer complete callback for channel1 */
215 hdac->DMA_Handle1->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh1;
216
217 /* Set the DMA error callback for channel1 */
218 hdac->DMA_Handle1->XferErrorCallback = DAC_DMAErrorCh1;
219
220 /* Enable the selected DAC channel1 DMA request */
221 SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN1);
222 }
223 else
224 {
225 /* Set the DMA transfer complete callback for channel2 */
226 hdac->DMA_Handle2->XferCpltCallback = DAC_DMAConvCpltCh2;
227
228 /* Set the DMA half transfer complete callback for channel2 */
229 hdac->DMA_Handle2->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh2;
230
231 /* Set the DMA error callback for channel2 */
232 hdac->DMA_Handle2->XferErrorCallback = DAC_DMAErrorCh2;
233
234 /* Enable the selected DAC channel2 DMA request */
235 SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN2);
236 }
237
238 switch (Alignment)
239 {
240 case DAC_ALIGN_12B_R:
241 /* Get DHR12R1 address */
242 tmpreg = (uint32_t)&hdac->Instance->DHR12RD;
243 break;
244 case DAC_ALIGN_12B_L:
245 /* Get DHR12L1 address */
246 tmpreg = (uint32_t)&hdac->Instance->DHR12LD;
247 break;
248 case DAC_ALIGN_8B_R:
249 /* Get DHR8R1 address */
250 tmpreg = (uint32_t)&hdac->Instance->DHR8RD;
251 break;
252 default:
253 break;
254 }
255
256 /* Enable the DMA channel */
257 if (Channel == DAC_CHANNEL_1)
258 {
259 /* Enable the DAC DMA underrun interrupt */
260 __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR1);
261
262 /* Enable the DMA channel */
263 status = HAL_DMA_Start_IT(hdac->DMA_Handle1, (uint32_t)pData, tmpreg, Length);
264 }
265 else
266 {
267 /* Enable the DAC DMA underrun interrupt */
268 __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR2);
269
270 /* Enable the DMA channel */
271 status = HAL_DMA_Start_IT(hdac->DMA_Handle2, (uint32_t)pData, tmpreg, Length);
272 }
273
274 /* Process Unlocked */
275 __HAL_UNLOCK(hdac);
276
277 if (status == HAL_OK)
278 {
279 /* Enable the Peripheral */
280 __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_1);
281 __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_2);
282 }
283 else
284 {
285 hdac->ErrorCode |= HAL_DAC_ERROR_DMA;
286 }
287
288 /* Return function status */
289 return status;
290 }
291
292 /**
293 * @brief Disables DAC and stop conversion both channel.
294 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
295 * the configuration information for the specified DAC.
296 * @param Channel The DAC channel that requests data from DMA.
297 * This parameter can be one of the following values:
298 * @arg DAC_CHANNEL_1: DAC Channel1 selected
299 * @arg DAC_CHANNEL_2: DAC Channel2 selected
300 * @retval HAL status
301 */
HAL_DACEx_DualStop_DMA(DAC_HandleTypeDef * hdac,uint32_t Channel)302 HAL_StatusTypeDef HAL_DACEx_DualStop_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel)
303 {
304 HAL_StatusTypeDef status;
305
306
307 /* Disable the selected DAC channel DMA request */
308 CLEAR_BIT(hdac->Instance->CR, DAC_CR_DMAEN2 | DAC_CR_DMAEN1);
309
310 /* Disable the Peripheral */
311 __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_1);
312 __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_2);
313
314 /* Disable the DMA channel */
315
316 /* Channel1 is used */
317 if (Channel == DAC_CHANNEL_1)
318 {
319 /* Disable the DMA channel */
320 status = HAL_DMA_Abort(hdac->DMA_Handle1);
321
322 /* Disable the DAC DMA underrun interrupt */
323 __HAL_DAC_DISABLE_IT(hdac, DAC_IT_DMAUDR1);
324 }
325 else
326 {
327 /* Disable the DMA channel */
328 status = HAL_DMA_Abort(hdac->DMA_Handle2);
329
330 /* Disable the DAC DMA underrun interrupt */
331 __HAL_DAC_DISABLE_IT(hdac, DAC_IT_DMAUDR2);
332 }
333
334 /* Check if DMA Channel effectively disabled */
335 if (status != HAL_OK)
336 {
337 /* Update DAC state machine to error */
338 hdac->State = HAL_DAC_STATE_ERROR;
339 }
340 else
341 {
342 /* Change DAC state */
343 hdac->State = HAL_DAC_STATE_READY;
344 }
345
346 /* Return function status */
347 return status;
348 }
349
350
351 /**
352 * @brief Enable or disable the selected DAC channel wave generation.
353 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
354 * the configuration information for the specified DAC.
355 * @param Channel The selected DAC channel.
356 * This parameter can be one of the following values:
357 * @arg DAC_CHANNEL_1: DAC Channel1 selected
358 * @arg DAC_CHANNEL_2: DAC Channel2 selected
359 * @param Amplitude Select max triangle amplitude.
360 * This parameter can be one of the following values:
361 * @arg DAC_TRIANGLEAMPLITUDE_1: Select max triangle amplitude of 1
362 * @arg DAC_TRIANGLEAMPLITUDE_3: Select max triangle amplitude of 3
363 * @arg DAC_TRIANGLEAMPLITUDE_7: Select max triangle amplitude of 7
364 * @arg DAC_TRIANGLEAMPLITUDE_15: Select max triangle amplitude of 15
365 * @arg DAC_TRIANGLEAMPLITUDE_31: Select max triangle amplitude of 31
366 * @arg DAC_TRIANGLEAMPLITUDE_63: Select max triangle amplitude of 63
367 * @arg DAC_TRIANGLEAMPLITUDE_127: Select max triangle amplitude of 127
368 * @arg DAC_TRIANGLEAMPLITUDE_255: Select max triangle amplitude of 255
369 * @arg DAC_TRIANGLEAMPLITUDE_511: Select max triangle amplitude of 511
370 * @arg DAC_TRIANGLEAMPLITUDE_1023: Select max triangle amplitude of 1023
371 * @arg DAC_TRIANGLEAMPLITUDE_2047: Select max triangle amplitude of 2047
372 * @arg DAC_TRIANGLEAMPLITUDE_4095: Select max triangle amplitude of 4095
373 * @retval HAL status
374 */
HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef * hdac,uint32_t Channel,uint32_t Amplitude)375 HAL_StatusTypeDef HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Amplitude)
376 {
377 /* Check the parameters */
378 assert_param(IS_DAC_CHANNEL(Channel));
379 assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude));
380
381 /* Process locked */
382 __HAL_LOCK(hdac);
383
384 /* Change DAC state */
385 hdac->State = HAL_DAC_STATE_BUSY;
386
387 /* Enable the triangle wave generation for the selected DAC channel */
388 MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1) | (DAC_CR_MAMP1)) << (Channel & 0x10UL),
389 (DAC_CR_WAVE1_1 | Amplitude) << (Channel & 0x10UL));
390
391 /* Change DAC state */
392 hdac->State = HAL_DAC_STATE_READY;
393
394 /* Process unlocked */
395 __HAL_UNLOCK(hdac);
396
397 /* Return function status */
398 return HAL_OK;
399 }
400
401 /**
402 * @brief Enable or disable the selected DAC channel wave generation.
403 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
404 * the configuration information for the specified DAC.
405 * @param Channel The selected DAC channel.
406 * This parameter can be one of the following values:
407 * @arg DAC_CHANNEL_1: DAC Channel1 selected
408 * @arg DAC_CHANNEL_2: DAC Channel2 selected
409 * @param Amplitude Unmask DAC channel LFSR for noise wave generation.
410 * This parameter can be one of the following values:
411 * @arg DAC_LFSRUNMASK_BIT0: Unmask DAC channel LFSR bit0 for noise wave generation
412 * @arg DAC_LFSRUNMASK_BITS1_0: Unmask DAC channel LFSR bit[1:0] for noise wave generation
413 * @arg DAC_LFSRUNMASK_BITS2_0: Unmask DAC channel LFSR bit[2:0] for noise wave generation
414 * @arg DAC_LFSRUNMASK_BITS3_0: Unmask DAC channel LFSR bit[3:0] for noise wave generation
415 * @arg DAC_LFSRUNMASK_BITS4_0: Unmask DAC channel LFSR bit[4:0] for noise wave generation
416 * @arg DAC_LFSRUNMASK_BITS5_0: Unmask DAC channel LFSR bit[5:0] for noise wave generation
417 * @arg DAC_LFSRUNMASK_BITS6_0: Unmask DAC channel LFSR bit[6:0] for noise wave generation
418 * @arg DAC_LFSRUNMASK_BITS7_0: Unmask DAC channel LFSR bit[7:0] for noise wave generation
419 * @arg DAC_LFSRUNMASK_BITS8_0: Unmask DAC channel LFSR bit[8:0] for noise wave generation
420 * @arg DAC_LFSRUNMASK_BITS9_0: Unmask DAC channel LFSR bit[9:0] for noise wave generation
421 * @arg DAC_LFSRUNMASK_BITS10_0: Unmask DAC channel LFSR bit[10:0] for noise wave generation
422 * @arg DAC_LFSRUNMASK_BITS11_0: Unmask DAC channel LFSR bit[11:0] for noise wave generation
423 * @retval HAL status
424 */
HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef * hdac,uint32_t Channel,uint32_t Amplitude)425 HAL_StatusTypeDef HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Amplitude)
426 {
427 /* Check the parameters */
428 assert_param(IS_DAC_CHANNEL(Channel));
429 assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude));
430
431 /* Process locked */
432 __HAL_LOCK(hdac);
433
434 /* Change DAC state */
435 hdac->State = HAL_DAC_STATE_BUSY;
436
437 /* Enable the noise wave generation for the selected DAC channel */
438 MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1) | (DAC_CR_MAMP1)) << (Channel & 0x10UL),
439 (DAC_CR_WAVE1_0 | Amplitude) << (Channel & 0x10UL));
440
441 /* Change DAC state */
442 hdac->State = HAL_DAC_STATE_READY;
443
444 /* Process unlocked */
445 __HAL_UNLOCK(hdac);
446
447 /* Return function status */
448 return HAL_OK;
449 }
450
451
452 /**
453 * @brief Set the specified data holding register value for dual DAC channel.
454 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
455 * the configuration information for the specified DAC.
456 * @param Alignment Specifies the data alignment for dual channel DAC.
457 * This parameter can be one of the following values:
458 * DAC_ALIGN_8B_R: 8bit right data alignment selected
459 * DAC_ALIGN_12B_L: 12bit left data alignment selected
460 * DAC_ALIGN_12B_R: 12bit right data alignment selected
461 * @param Data1 Data for DAC Channel1 to be loaded in the selected data holding register.
462 * @param Data2 Data for DAC Channel2 to be loaded in the selected data holding register.
463 * @note In dual mode, a unique register access is required to write in both
464 * DAC channels at the same time.
465 * @retval HAL status
466 */
HAL_DACEx_DualSetValue(DAC_HandleTypeDef * hdac,uint32_t Alignment,uint32_t Data1,uint32_t Data2)467 HAL_StatusTypeDef HAL_DACEx_DualSetValue(DAC_HandleTypeDef *hdac, uint32_t Alignment, uint32_t Data1, uint32_t Data2)
468 {
469 uint32_t data;
470 uint32_t tmp;
471
472 /* Check the parameters */
473 assert_param(IS_DAC_ALIGN(Alignment));
474 assert_param(IS_DAC_DATA(Data1));
475 assert_param(IS_DAC_DATA(Data2));
476
477 /* Calculate and set dual DAC data holding register value */
478 if (Alignment == DAC_ALIGN_8B_R)
479 {
480 data = ((uint32_t)Data2 << 8U) | Data1;
481 }
482 else
483 {
484 data = ((uint32_t)Data2 << 16U) | Data1;
485 }
486
487 tmp = (uint32_t)hdac->Instance;
488 tmp += DAC_DHR12RD_ALIGNMENT(Alignment);
489
490 /* Set the dual DAC selected data holding register */
491 *(__IO uint32_t *)tmp = data;
492
493 /* Return function status */
494 return HAL_OK;
495 }
496
497 /**
498 * @brief Conversion complete callback in non-blocking mode for Channel2.
499 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
500 * the configuration information for the specified DAC.
501 * @retval None
502 */
HAL_DACEx_ConvCpltCallbackCh2(DAC_HandleTypeDef * hdac)503 __weak void HAL_DACEx_ConvCpltCallbackCh2(DAC_HandleTypeDef *hdac)
504 {
505 /* Prevent unused argument(s) compilation warning */
506 UNUSED(hdac);
507
508 /* NOTE : This function should not be modified, when the callback is needed,
509 the HAL_DACEx_ConvCpltCallbackCh2 could be implemented in the user file
510 */
511 }
512
513 /**
514 * @brief Conversion half DMA transfer callback in non-blocking mode for Channel2.
515 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
516 * the configuration information for the specified DAC.
517 * @retval None
518 */
HAL_DACEx_ConvHalfCpltCallbackCh2(DAC_HandleTypeDef * hdac)519 __weak void HAL_DACEx_ConvHalfCpltCallbackCh2(DAC_HandleTypeDef *hdac)
520 {
521 /* Prevent unused argument(s) compilation warning */
522 UNUSED(hdac);
523
524 /* NOTE : This function should not be modified, when the callback is needed,
525 the HAL_DACEx_ConvHalfCpltCallbackCh2 could be implemented in the user file
526 */
527 }
528
529 /**
530 * @brief Error DAC callback for Channel2.
531 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
532 * the configuration information for the specified DAC.
533 * @retval None
534 */
HAL_DACEx_ErrorCallbackCh2(DAC_HandleTypeDef * hdac)535 __weak void HAL_DACEx_ErrorCallbackCh2(DAC_HandleTypeDef *hdac)
536 {
537 /* Prevent unused argument(s) compilation warning */
538 UNUSED(hdac);
539
540 /* NOTE : This function should not be modified, when the callback is needed,
541 the HAL_DACEx_ErrorCallbackCh2 could be implemented in the user file
542 */
543 }
544
545 /**
546 * @brief DMA underrun DAC callback for Channel2.
547 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
548 * the configuration information for the specified DAC.
549 * @retval None
550 */
HAL_DACEx_DMAUnderrunCallbackCh2(DAC_HandleTypeDef * hdac)551 __weak void HAL_DACEx_DMAUnderrunCallbackCh2(DAC_HandleTypeDef *hdac)
552 {
553 /* Prevent unused argument(s) compilation warning */
554 UNUSED(hdac);
555
556 /* NOTE : This function should not be modified, when the callback is needed,
557 the HAL_DACEx_DMAUnderrunCallbackCh2 could be implemented in the user file
558 */
559 }
560
561
562 /**
563 * @brief Run the self calibration of one DAC channel.
564 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
565 * the configuration information for the specified DAC.
566 * @param sConfig DAC channel configuration structure.
567 * @param Channel The selected DAC channel.
568 * This parameter can be one of the following values:
569 * @arg DAC_CHANNEL_1: DAC Channel1 selected
570 * @arg DAC_CHANNEL_2: DAC Channel2 selected
571 * @retval Updates DAC_TrimmingValue. , DAC_UserTrimming set to DAC_UserTrimming
572 * @retval HAL status
573 * @note Calibration runs about 7 ms.
574 */
HAL_DACEx_SelfCalibrate(DAC_HandleTypeDef * hdac,DAC_ChannelConfTypeDef * sConfig,uint32_t Channel)575 HAL_StatusTypeDef HAL_DACEx_SelfCalibrate(DAC_HandleTypeDef *hdac, DAC_ChannelConfTypeDef *sConfig, uint32_t Channel)
576 {
577 HAL_StatusTypeDef status = HAL_OK;
578
579 __IO uint32_t tmp;
580 uint32_t trimmingvalue;
581 uint32_t delta;
582
583 /* store/restore channel configuration structure purpose */
584 uint32_t oldmodeconfiguration;
585
586 /* Check the parameters */
587 assert_param(IS_DAC_CHANNEL(Channel));
588
589 /* Check the DAC handle allocation */
590 /* Check if DAC running */
591 if (hdac == NULL)
592 {
593 status = HAL_ERROR;
594 }
595 else if (hdac->State == HAL_DAC_STATE_BUSY)
596 {
597 status = HAL_ERROR;
598 }
599 else
600 {
601 /* Process locked */
602 __HAL_LOCK(hdac);
603
604 /* Store configuration */
605 oldmodeconfiguration = (hdac->Instance->MCR & (DAC_MCR_MODE1 << (Channel & 0x10UL)));
606
607 /* Disable the selected DAC channel */
608 CLEAR_BIT((hdac->Instance->CR), (DAC_CR_EN1 << (Channel & 0x10UL)));
609
610 /* Set mode in MCR for calibration */
611 MODIFY_REG(hdac->Instance->MCR, (DAC_MCR_MODE1 << (Channel & 0x10UL)), 0U);
612
613 /* Set DAC Channel1 DHR register to the middle value */
614 tmp = (uint32_t)hdac->Instance;
615
616 if (Channel == DAC_CHANNEL_1)
617 {
618 tmp += DAC_DHR12R1_ALIGNMENT(DAC_ALIGN_12B_R);
619 }
620 else
621 {
622 tmp += DAC_DHR12R2_ALIGNMENT(DAC_ALIGN_12B_R);
623 }
624
625 *(__IO uint32_t *) tmp = 0x0800UL;
626
627 /* Enable the selected DAC channel calibration */
628 /* i.e. set DAC_CR_CENx bit */
629 SET_BIT((hdac->Instance->CR), (DAC_CR_CEN1 << (Channel & 0x10UL)));
630
631 /* Init trimming counter */
632 /* Medium value */
633 trimmingvalue = 16UL;
634 delta = 8UL;
635 while (delta != 0UL)
636 {
637 /* Set candidate trimming */
638 MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (trimmingvalue << (Channel & 0x10UL)));
639
640 /* tOFFTRIMmax delay x ms as per datasheet (electrical characteristics */
641 /* i.e. minimum time needed between two calibration steps */
642 HAL_Delay(1UL);
643
644 if ((hdac->Instance->SR & (DAC_SR_CAL_FLAG1 << (Channel & 0x10UL))) == (DAC_SR_CAL_FLAG1 << (Channel & 0x10UL)))
645 {
646 /* DAC_SR_CAL_FLAGx is HIGH try higher trimming */
647 trimmingvalue -= delta;
648 }
649 else
650 {
651 /* DAC_SR_CAL_FLAGx is LOW try lower trimming */
652 trimmingvalue += delta;
653 }
654 delta >>= 1UL;
655 }
656
657 /* Still need to check if right calibration is current value or one step below */
658 /* Indeed the first value that causes the DAC_SR_CAL_FLAGx bit to change from 0 to 1 */
659 /* Set candidate trimming */
660 MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (trimmingvalue << (Channel & 0x10UL)));
661
662 /* tOFFTRIMmax delay x ms as per datasheet (electrical characteristics */
663 /* i.e. minimum time needed between two calibration steps */
664 HAL_Delay(1UL);
665
666 if ((hdac->Instance->SR & (DAC_SR_CAL_FLAG1 << (Channel & 0x10UL))) == 0UL)
667 {
668 /* Trimming is actually one value more */
669 trimmingvalue++;
670 /* Set right trimming */
671 MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (trimmingvalue << (Channel & 0x10UL)));
672 }
673
674 /* Disable the selected DAC channel calibration */
675 /* i.e. clear DAC_CR_CENx bit */
676 CLEAR_BIT((hdac->Instance->CR), (DAC_CR_CEN1 << (Channel & 0x10UL)));
677
678 sConfig->DAC_TrimmingValue = trimmingvalue;
679 sConfig->DAC_UserTrimming = DAC_TRIMMING_USER;
680
681 /* Restore configuration */
682 MODIFY_REG(hdac->Instance->MCR, (DAC_MCR_MODE1 << (Channel & 0x10UL)), oldmodeconfiguration);
683
684 /* Process unlocked */
685 __HAL_UNLOCK(hdac);
686 }
687
688 return status;
689 }
690
691 /**
692 * @brief Set the trimming mode and trimming value (user trimming mode applied).
693 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
694 * the configuration information for the specified DAC.
695 * @param sConfig DAC configuration structure updated with new DAC trimming value.
696 * @param Channel The selected DAC channel.
697 * This parameter can be one of the following values:
698 * @arg DAC_CHANNEL_1: DAC Channel1 selected
699 * @arg DAC_CHANNEL_2: DAC Channel2 selected
700 * @param NewTrimmingValue DAC new trimming value
701 * @retval HAL status
702 */
HAL_DACEx_SetUserTrimming(DAC_HandleTypeDef * hdac,DAC_ChannelConfTypeDef * sConfig,uint32_t Channel,uint32_t NewTrimmingValue)703 HAL_StatusTypeDef HAL_DACEx_SetUserTrimming(DAC_HandleTypeDef *hdac, DAC_ChannelConfTypeDef *sConfig, uint32_t Channel,
704 uint32_t NewTrimmingValue)
705 {
706 HAL_StatusTypeDef status = HAL_OK;
707
708 /* Check the parameters */
709 assert_param(IS_DAC_CHANNEL(Channel));
710 assert_param(IS_DAC_NEWTRIMMINGVALUE(NewTrimmingValue));
711
712 /* Check the DAC handle allocation */
713 if (hdac == NULL)
714 {
715 status = HAL_ERROR;
716 }
717 else
718 {
719 /* Process locked */
720 __HAL_LOCK(hdac);
721
722 /* Set new trimming */
723 MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (NewTrimmingValue << (Channel & 0x10UL)));
724
725 /* Update trimming mode */
726 sConfig->DAC_UserTrimming = DAC_TRIMMING_USER;
727 sConfig->DAC_TrimmingValue = NewTrimmingValue;
728
729 /* Process unlocked */
730 __HAL_UNLOCK(hdac);
731 }
732 return status;
733 }
734
735 /**
736 * @brief Return the DAC trimming value.
737 * @param hdac DAC handle
738 * @param Channel The selected DAC channel.
739 * This parameter can be one of the following values:
740 * @arg DAC_CHANNEL_1: DAC Channel1 selected
741 * @arg DAC_CHANNEL_2: DAC Channel2 selected
742 * @retval Trimming value : range: 0->31
743 *
744 */
HAL_DACEx_GetTrimOffset(DAC_HandleTypeDef * hdac,uint32_t Channel)745 uint32_t HAL_DACEx_GetTrimOffset(DAC_HandleTypeDef *hdac, uint32_t Channel)
746 {
747 /* Check the parameter */
748 assert_param(IS_DAC_CHANNEL(Channel));
749
750 /* Retrieve trimming */
751 return ((hdac->Instance->CCR & (DAC_CCR_OTRIM1 << (Channel & 0x10UL))) >> (Channel & 0x10UL));
752 }
753
754 /**
755 * @}
756 */
757
758 /** @defgroup DACEx_Exported_Functions_Group3 Peripheral Control functions
759 * @brief Extended Peripheral Control functions
760 *
761 @verbatim
762 ==============================================================================
763 ##### Peripheral Control functions #####
764 ==============================================================================
765 [..] This section provides functions allowing to:
766 (+) Set the specified data holding register value for DAC channel.
767
768 @endverbatim
769 * @{
770 */
771
772
773 /**
774 * @brief Return the last data output value of the selected DAC channel.
775 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
776 * the configuration information for the specified DAC.
777 * @retval The selected DAC channel data output value.
778 */
HAL_DACEx_DualGetValue(DAC_HandleTypeDef * hdac)779 uint32_t HAL_DACEx_DualGetValue(DAC_HandleTypeDef *hdac)
780 {
781 uint32_t tmp = 0UL;
782
783 tmp |= hdac->Instance->DOR1;
784
785 tmp |= hdac->Instance->DOR2 << 16UL;
786
787 /* Returns the DAC channel data output register value */
788 return tmp;
789 }
790
791
792 /**
793 * @}
794 */
795 /**
796 * @}
797 */
798
799 /* Private functions ---------------------------------------------------------*/
800 /** @defgroup DACEx_Private_Functions DACEx private functions
801 * @brief Extended private functions
802 * @{
803 */
804
805
806 /**
807 * @brief DMA conversion complete callback.
808 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
809 * the configuration information for the specified DMA module.
810 * @retval None
811 */
DAC_DMAConvCpltCh2(DMA_HandleTypeDef * hdma)812 void DAC_DMAConvCpltCh2(DMA_HandleTypeDef *hdma)
813 {
814 DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
815
816 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
817 hdac->ConvCpltCallbackCh2(hdac);
818 #else
819 HAL_DACEx_ConvCpltCallbackCh2(hdac);
820 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
821
822 hdac->State = HAL_DAC_STATE_READY;
823 }
824
825 /**
826 * @brief DMA half transfer complete callback.
827 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
828 * the configuration information for the specified DMA module.
829 * @retval None
830 */
DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef * hdma)831 void DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef *hdma)
832 {
833 DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
834 /* Conversion complete callback */
835 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
836 hdac->ConvHalfCpltCallbackCh2(hdac);
837 #else
838 HAL_DACEx_ConvHalfCpltCallbackCh2(hdac);
839 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
840 }
841
842 /**
843 * @brief DMA error callback.
844 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
845 * the configuration information for the specified DMA module.
846 * @retval None
847 */
DAC_DMAErrorCh2(DMA_HandleTypeDef * hdma)848 void DAC_DMAErrorCh2(DMA_HandleTypeDef *hdma)
849 {
850 DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
851
852 /* Set DAC error code to DMA error */
853 hdac->ErrorCode |= HAL_DAC_ERROR_DMA;
854
855 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
856 hdac->ErrorCallbackCh2(hdac);
857 #else
858 HAL_DACEx_ErrorCallbackCh2(hdac);
859 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
860
861 hdac->State = HAL_DAC_STATE_READY;
862 }
863
864
865 /**
866 * @}
867 */
868
869 /**
870 * @}
871 */
872
873 #endif /* DAC1 */
874
875 #endif /* HAL_DAC_MODULE_ENABLED */
876
877 /**
878 * @}
879 */
880
881