1 /**
2 ******************************************************************************
3 * @file stm32u5xx_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) 2021 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 *** Dual mode IO operation ***
27 ==============================
28 [..]
29 (+) Use HAL_DACEx_DualStart() to enable both channel and start conversion
30 for dual mode operation.
31 If software trigger is selected, using HAL_DACEx_DualStart() will start
32 the conversion of the value previously set by HAL_DACEx_DualSetValue().
33 (+) Use HAL_DACEx_DualStop() to disable both channel and stop conversion
34 for dual mode operation.
35 (+) Use HAL_DACEx_DualStart_DMA() to enable both channel and start conversion
36 for dual mode operation using DMA to feed DAC converters.
37 First issued trigger will start the conversion of the value previously
38 set by HAL_DACEx_DualSetValue().
39 The same callbacks that are used in single mode are called in dual mode to notify
40 transfer completion (half complete or complete), errors or underrun.
41 (+) Use HAL_DACEx_DualStop_DMA() to disable both channel and stop conversion
42 for dual mode operation using DMA to feed DAC converters.
43 (+) When Dual mode is enabled (i.e. DAC Channel1 and Channel2 are used simultaneously) :
44 Use HAL_DACEx_DualGetValue() to get digital data to be converted and use
45 HAL_DACEx_DualSetValue() to set digital value to converted simultaneously in
46 Channel 1 and Channel 2.
47 *** Signal generation operation ***
48 ===================================
49 [..]
50 (+) Use HAL_DACEx_TriangleWaveGenerate() to generate Triangle signal.
51 (+) Use HAL_DACEx_NoiseWaveGenerate() to generate Noise signal.
52
53 (+) HAL_DACEx_SelfCalibrate to calibrate one DAC channel.
54 (+) HAL_DACEx_SetUserTrimming to set user trimming value.
55 (+) HAL_DACEx_GetTrimOffset to retrieve trimming value (factory setting
56 after reset, user setting if HAL_DACEx_SetUserTrimming have been used
57 at least one time after reset).
58
59 *** Autonomous Mode operation ***
60 ===================================
61 [..]
62 (+) Use HAL_DACx_SetConfigAutonomousMode() to configure the autonomous mode
63 (+) Use HAL_DACx_GetConfigAutonomousMode() to get the current configuration of the autonomous mode
64 (+) Use HAL_DACx_ClearConfigAutonomousMode() to clear the configuration of the autonomous mode
65
66 @endverbatim
67 ******************************************************************************
68 */
69
70
71 /* Includes ------------------------------------------------------------------*/
72 #include "stm32u5xx_hal.h"
73
74 /** @addtogroup STM32U5xx_HAL_Driver
75 * @{
76 */
77
78 #ifdef HAL_DAC_MODULE_ENABLED
79
80 #if defined(DAC1)
81
82 /** @defgroup DACEx DACEx
83 * @brief DAC Extended HAL module driver
84 * @{
85 */
86
87 /* Private typedef -----------------------------------------------------------*/
88 /* Private define ------------------------------------------------------------*/
89
90 /* Delay for DAC minimum trimming time. */
91 /* Note: minimum time needed between two calibration steps */
92 /* The delay below is specified under conditions: */
93 /* - DAC channel output buffer enabled */
94 /* Literal set to maximum value (refer to device datasheet, */
95 /* electrical characteristics, parameter "tTRIM"). */
96 /* Unit: us */
97 #define DAC_DELAY_TRIM_US (50UL) /*!< Delay for DAC minimum trimming time */
98
99 /* Private macro -------------------------------------------------------------*/
100 /* Private variables ---------------------------------------------------------*/
101 /* Private function prototypes -----------------------------------------------*/
102 /* Exported functions --------------------------------------------------------*/
103
104 /** @defgroup DACEx_Exported_Functions DACEx Exported Functions
105 * @{
106 */
107
108 /** @defgroup DACEx_Exported_Functions_Group2 IO operation functions
109 * @brief Extended IO operation functions
110 *
111 @verbatim
112 ==============================================================================
113 ##### Extended features functions #####
114 ==============================================================================
115 [..] This section provides functions allowing to:
116 (+) Start conversion.
117 (+) Stop conversion.
118 (+) Start conversion and enable DMA transfer.
119 (+) Stop conversion and disable DMA transfer.
120 (+) Get result of conversion.
121 (+) Get result of dual mode conversion.
122
123 @endverbatim
124 * @{
125 */
126
127
128 /**
129 * @brief Enables DAC and starts conversion of both channels.
130 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
131 * the configuration information for the specified DAC.
132 * @retval HAL status
133 */
HAL_DACEx_DualStart(DAC_HandleTypeDef * hdac)134 HAL_StatusTypeDef HAL_DACEx_DualStart(DAC_HandleTypeDef *hdac)
135 {
136 uint32_t tmp_swtrig = 0UL;
137 __IO uint32_t wait_loop_index;
138
139 /* Check the DAC peripheral handle */
140 if (hdac == NULL)
141 {
142 return HAL_ERROR;
143 }
144
145
146 /* Process locked */
147 __HAL_LOCK(hdac);
148
149 /* Change DAC state */
150 hdac->State = HAL_DAC_STATE_BUSY;
151
152 /* Enable the Peripheral */
153 __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_1);
154 __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_2);
155 /* Ensure minimum wait before using peripheral after enabling it */
156 /* Wait loop initialization and execution */
157 /* Note: Variable divided by 2 to compensate partially */
158 /* CPU processing cycles, scaling in us split to not */
159 /* exceed 32 bits register capacity and handle low frequency. */
160 wait_loop_index = ((DAC_DELAY_STARTUP_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
161 while (wait_loop_index != 0UL)
162 {
163 wait_loop_index--;
164 }
165
166 /* Check if software trigger enabled */
167 if ((hdac->Instance->CR & (DAC_CR_TEN1 | DAC_CR_TSEL1)) == DAC_TRIGGER_SOFTWARE)
168 {
169 tmp_swtrig |= DAC_SWTRIGR_SWTRIG1;
170 }
171 if ((hdac->Instance->CR & (DAC_CR_TEN2 | DAC_CR_TSEL2)) == (DAC_TRIGGER_SOFTWARE << (DAC_CHANNEL_2 & 0x10UL)))
172 {
173 tmp_swtrig |= DAC_SWTRIGR_SWTRIG2;
174 }
175 /* Enable the selected DAC software conversion*/
176 SET_BIT(hdac->Instance->SWTRIGR, tmp_swtrig);
177
178 /* Change DAC state */
179 hdac->State = HAL_DAC_STATE_READY;
180
181 /* Process unlocked */
182 __HAL_UNLOCK(hdac);
183
184 /* Return function status */
185 return HAL_OK;
186 }
187
188 /**
189 * @brief Disables DAC and stop conversion of both channels.
190 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
191 * the configuration information for the specified DAC.
192 * @retval HAL status
193 */
HAL_DACEx_DualStop(DAC_HandleTypeDef * hdac)194 HAL_StatusTypeDef HAL_DACEx_DualStop(DAC_HandleTypeDef *hdac)
195 {
196 /* Check the DAC peripheral handle */
197 if (hdac == NULL)
198 {
199 return HAL_ERROR;
200 }
201
202
203 /* Disable the Peripheral */
204 __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_1);
205 __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_2);
206
207 /* Change DAC state */
208 hdac->State = HAL_DAC_STATE_READY;
209
210 /* Return function status */
211 return HAL_OK;
212 }
213
214 /**
215 * @brief Enables DAC and starts conversion of both channel 1 and 2 of the same DAC.
216 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
217 * the configuration information for the specified DAC.
218 * @param Channel The DAC channel that will request data from DMA.
219 * This parameter can be one of the following values:
220 * @arg DAC_CHANNEL_1: DAC Channel1 selected
221 * @arg DAC_CHANNEL_2: DAC Channel2 selected
222 * @param pData The destination peripheral Buffer address.
223 * @param Length The length of data to be transferred from memory to DAC peripheral
224 * @param Alignment Specifies the data alignment for DAC channel.
225 * This parameter can be one of the following values:
226 * @arg DAC_ALIGN_8B_R: 8bit right data alignment selected
227 * @arg DAC_ALIGN_12B_L: 12bit left data alignment selected
228 * @arg DAC_ALIGN_12B_R: 12bit right data alignment selected
229 * @retval HAL status
230 */
HAL_DACEx_DualStart_DMA(DAC_HandleTypeDef * hdac,uint32_t Channel,const uint32_t * pData,uint32_t Length,uint32_t Alignment)231 HAL_StatusTypeDef HAL_DACEx_DualStart_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel,
232 const uint32_t *pData, uint32_t Length, uint32_t Alignment)
233 {
234 HAL_StatusTypeDef status;
235 uint32_t tmpreg = 0UL;
236 __IO uint32_t wait_loop_index;
237 uint32_t LengthInBytes;
238
239 /* Check the DAC peripheral handle */
240 if (hdac == NULL)
241 {
242 return HAL_ERROR;
243 }
244
245 /* Check the parameters */
246 assert_param(IS_DAC_CHANNEL(Channel));
247 assert_param(IS_DAC_ALIGN(Alignment));
248
249 /* Process locked */
250 __HAL_LOCK(hdac);
251
252 /* Change DAC state */
253 hdac->State = HAL_DAC_STATE_BUSY;
254
255 if (Channel == DAC_CHANNEL_1)
256 {
257 /* Set the DMA transfer complete callback for channel1 */
258 hdac->DMA_Handle1->XferCpltCallback = DAC_DMAConvCpltCh1;
259
260 /* Set the DMA half transfer complete callback for channel1 */
261 hdac->DMA_Handle1->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh1;
262
263 /* Set the DMA error callback for channel1 */
264 hdac->DMA_Handle1->XferErrorCallback = DAC_DMAErrorCh1;
265
266 /* Enable the selected DAC channel1 DMA request */
267 SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN1);
268 }
269 else
270 {
271 /* Set the DMA transfer complete callback for channel2 */
272 hdac->DMA_Handle2->XferCpltCallback = DAC_DMAConvCpltCh2;
273
274 /* Set the DMA half transfer complete callback for channel2 */
275 hdac->DMA_Handle2->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh2;
276
277 /* Set the DMA error callback for channel2 */
278 hdac->DMA_Handle2->XferErrorCallback = DAC_DMAErrorCh2;
279
280 /* Enable the selected DAC channel2 DMA request */
281 SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN2);
282 }
283
284 switch (Alignment)
285 {
286 case DAC_ALIGN_12B_R:
287 /* Get DHR12R1 address */
288 tmpreg = (uint32_t)&hdac->Instance->DHR12RD;
289 break;
290 case DAC_ALIGN_12B_L:
291 /* Get DHR12L1 address */
292 tmpreg = (uint32_t)&hdac->Instance->DHR12LD;
293 break;
294 case DAC_ALIGN_8B_R:
295 /* Get DHR8R1 address */
296 tmpreg = (uint32_t)&hdac->Instance->DHR8RD;
297 break;
298 default:
299 break;
300 }
301
302 /* Enable the DMA channel */
303 if (Channel == DAC_CHANNEL_1)
304 {
305 /* Enable the DAC DMA underrun interrupt */
306 __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR1);
307
308 /* Length should be converted to number of bytes */
309 LengthInBytes = Length * 4U;
310
311 /* Check linkedlist mode */
312 if ((hdac->DMA_Handle1->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
313 {
314 if ((hdac->DMA_Handle1->LinkedListQueue != NULL) && (hdac->DMA_Handle1->LinkedListQueue->Head != NULL))
315 {
316 /* Set DMA data size */
317 hdac->DMA_Handle1->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = LengthInBytes;
318
319 /* Set DMA source address */
320 hdac->DMA_Handle1->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pData;
321
322 /* Set DMA destination address */
323 hdac->DMA_Handle1->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = tmpreg;
324
325 /* Enable the DMA channel */
326 status = HAL_DMAEx_List_Start_IT(hdac->DMA_Handle1);
327 }
328 else
329 {
330 /* Return error status */
331 return HAL_ERROR;
332 }
333 }
334 else
335 {
336 /* Enable the DMA channel */
337 status = HAL_DMA_Start_IT(hdac->DMA_Handle1, (uint32_t)pData, tmpreg, LengthInBytes);
338 }
339 }
340 else
341 {
342 /* Enable the DAC DMA underrun interrupt */
343 __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR2);
344
345 /* Length should be converted to number of bytes */
346 LengthInBytes = Length * 4U;
347
348 /* Check linkedlist mode */
349 if ((hdac->DMA_Handle2->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
350 {
351 if ((hdac->DMA_Handle2->LinkedListQueue != NULL) && (hdac->DMA_Handle2->LinkedListQueue->Head != NULL))
352 {
353 /* Set DMA data size */
354 hdac->DMA_Handle2->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = LengthInBytes;
355
356 /* Set DMA source address */
357 hdac->DMA_Handle2->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pData;
358
359 /* Set DMA destination address */
360 hdac->DMA_Handle2->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = tmpreg;
361
362 /* Enable the DMA channel */
363 status = HAL_DMAEx_List_Start_IT(hdac->DMA_Handle2);
364 }
365 else
366 {
367 /* Return error status */
368 return HAL_ERROR;
369 }
370 }
371 else
372 {
373 /* Enable the DMA channel */
374 status = HAL_DMA_Start_IT(hdac->DMA_Handle2, (uint32_t)pData, tmpreg, LengthInBytes);
375 }
376 }
377
378 /* Process Unlocked */
379 __HAL_UNLOCK(hdac);
380
381 if (status == HAL_OK)
382 {
383 /* Enable the Peripheral */
384 __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_1);
385 __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_2);
386 /* Ensure minimum wait before using peripheral after enabling it */
387 /* Wait loop initialization and execution */
388 /* Note: Variable divided by 2 to compensate partially */
389 /* CPU processing cycles, scaling in us split to not */
390 /* exceed 32 bits register capacity and handle low frequency. */
391 wait_loop_index = ((DAC_DELAY_STARTUP_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
392 while (wait_loop_index != 0UL)
393 {
394 wait_loop_index--;
395 }
396 }
397 else
398 {
399 hdac->ErrorCode |= HAL_DAC_ERROR_DMA;
400 }
401
402 /* Return function status */
403 return status;
404 }
405
406 /**
407 * @brief Disables DAC and stop conversion both channel.
408 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
409 * the configuration information for the specified DAC.
410 * @param Channel The DAC channel that requests data from DMA.
411 * This parameter can be one of the following values:
412 * @arg DAC_CHANNEL_1: DAC Channel1 selected
413 * @arg DAC_CHANNEL_2: DAC Channel2 selected
414 * @retval HAL status
415 */
HAL_DACEx_DualStop_DMA(DAC_HandleTypeDef * hdac,uint32_t Channel)416 HAL_StatusTypeDef HAL_DACEx_DualStop_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel)
417 {
418 HAL_StatusTypeDef status;
419
420 /* Check the DAC peripheral handle */
421 if (hdac == NULL)
422 {
423 return HAL_ERROR;
424 }
425
426
427 /* Disable the selected DAC channel DMA request */
428 CLEAR_BIT(hdac->Instance->CR, DAC_CR_DMAEN2 | DAC_CR_DMAEN1);
429
430 /* Disable the Peripheral */
431 __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_1);
432 __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_2);
433
434 /* Disable the DMA channel */
435
436 /* Channel1 is used */
437 if (Channel == DAC_CHANNEL_1)
438 {
439 /* Disable the DMA channel */
440 status = HAL_DMA_Abort(hdac->DMA_Handle1);
441
442 /* Disable the DAC DMA underrun interrupt */
443 __HAL_DAC_DISABLE_IT(hdac, DAC_IT_DMAUDR1);
444 }
445 else
446 {
447 /* Disable the DMA channel */
448 status = HAL_DMA_Abort(hdac->DMA_Handle2);
449
450 /* Disable the DAC DMA underrun interrupt */
451 __HAL_DAC_DISABLE_IT(hdac, DAC_IT_DMAUDR2);
452 }
453
454 /* Check if DMA Channel effectively disabled */
455 if (status != HAL_OK)
456 {
457 /* Update DAC state machine to error */
458 hdac->State = HAL_DAC_STATE_ERROR;
459 }
460 else
461 {
462 /* Change DAC state */
463 hdac->State = HAL_DAC_STATE_READY;
464 }
465
466 /* Return function status */
467 return status;
468 }
469
470
471 /**
472 * @brief Enable or disable the selected DAC channel wave generation.
473 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
474 * the configuration information for the specified DAC.
475 * @param Channel The selected DAC channel.
476 * This parameter can be one of the following values:
477 * @arg DAC_CHANNEL_1: DAC Channel1 selected
478 * @arg DAC_CHANNEL_2: DAC Channel2 selected
479 * @param Amplitude Select max triangle amplitude.
480 * This parameter can be one of the following values:
481 * @arg DAC_TRIANGLEAMPLITUDE_1: Select max triangle amplitude of 1
482 * @arg DAC_TRIANGLEAMPLITUDE_3: Select max triangle amplitude of 3
483 * @arg DAC_TRIANGLEAMPLITUDE_7: Select max triangle amplitude of 7
484 * @arg DAC_TRIANGLEAMPLITUDE_15: Select max triangle amplitude of 15
485 * @arg DAC_TRIANGLEAMPLITUDE_31: Select max triangle amplitude of 31
486 * @arg DAC_TRIANGLEAMPLITUDE_63: Select max triangle amplitude of 63
487 * @arg DAC_TRIANGLEAMPLITUDE_127: Select max triangle amplitude of 127
488 * @arg DAC_TRIANGLEAMPLITUDE_255: Select max triangle amplitude of 255
489 * @arg DAC_TRIANGLEAMPLITUDE_511: Select max triangle amplitude of 511
490 * @arg DAC_TRIANGLEAMPLITUDE_1023: Select max triangle amplitude of 1023
491 * @arg DAC_TRIANGLEAMPLITUDE_2047: Select max triangle amplitude of 2047
492 * @arg DAC_TRIANGLEAMPLITUDE_4095: Select max triangle amplitude of 4095
493 * @retval HAL status
494 */
HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef * hdac,uint32_t Channel,uint32_t Amplitude)495 HAL_StatusTypeDef HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Amplitude)
496 {
497 /* Check the DAC peripheral handle */
498 if (hdac == NULL)
499 {
500 return HAL_ERROR;
501 }
502
503 /* Check the parameters */
504 assert_param(IS_DAC_CHANNEL(Channel));
505 assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude));
506
507 /* Process locked */
508 __HAL_LOCK(hdac);
509
510 /* Change DAC state */
511 hdac->State = HAL_DAC_STATE_BUSY;
512
513 /* Enable the triangle wave generation for the selected DAC channel */
514 MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1) | (DAC_CR_MAMP1)) << (Channel & 0x10UL),
515 (DAC_CR_WAVE1_1 | Amplitude) << (Channel & 0x10UL));
516
517 /* Change DAC state */
518 hdac->State = HAL_DAC_STATE_READY;
519
520 /* Process unlocked */
521 __HAL_UNLOCK(hdac);
522
523 /* Return function status */
524 return HAL_OK;
525 }
526
527 /**
528 * @brief Enable or disable the selected DAC channel wave generation.
529 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
530 * the configuration information for the specified DAC.
531 * @param Channel The selected DAC channel.
532 * This parameter can be one of the following values:
533 * @arg DAC_CHANNEL_1: DAC Channel1 selected
534 * @arg DAC_CHANNEL_2: DAC Channel2 selected
535 * @param Amplitude Unmask DAC channel LFSR for noise wave generation.
536 * This parameter can be one of the following values:
537 * @arg DAC_LFSRUNMASK_BIT0: Unmask DAC channel LFSR bit0 for noise wave generation
538 * @arg DAC_LFSRUNMASK_BITS1_0: Unmask DAC channel LFSR bit[1:0] for noise wave generation
539 * @arg DAC_LFSRUNMASK_BITS2_0: Unmask DAC channel LFSR bit[2:0] for noise wave generation
540 * @arg DAC_LFSRUNMASK_BITS3_0: Unmask DAC channel LFSR bit[3:0] for noise wave generation
541 * @arg DAC_LFSRUNMASK_BITS4_0: Unmask DAC channel LFSR bit[4:0] for noise wave generation
542 * @arg DAC_LFSRUNMASK_BITS5_0: Unmask DAC channel LFSR bit[5:0] for noise wave generation
543 * @arg DAC_LFSRUNMASK_BITS6_0: Unmask DAC channel LFSR bit[6:0] for noise wave generation
544 * @arg DAC_LFSRUNMASK_BITS7_0: Unmask DAC channel LFSR bit[7:0] for noise wave generation
545 * @arg DAC_LFSRUNMASK_BITS8_0: Unmask DAC channel LFSR bit[8:0] for noise wave generation
546 * @arg DAC_LFSRUNMASK_BITS9_0: Unmask DAC channel LFSR bit[9:0] for noise wave generation
547 * @arg DAC_LFSRUNMASK_BITS10_0: Unmask DAC channel LFSR bit[10:0] for noise wave generation
548 * @arg DAC_LFSRUNMASK_BITS11_0: Unmask DAC channel LFSR bit[11:0] for noise wave generation
549 * @retval HAL status
550 */
HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef * hdac,uint32_t Channel,uint32_t Amplitude)551 HAL_StatusTypeDef HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Amplitude)
552 {
553 /* Check the DAC peripheral handle */
554 if (hdac == NULL)
555 {
556 return HAL_ERROR;
557 }
558
559 /* Check the parameters */
560 assert_param(IS_DAC_CHANNEL(Channel));
561 assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude));
562
563 /* Process locked */
564 __HAL_LOCK(hdac);
565
566 /* Change DAC state */
567 hdac->State = HAL_DAC_STATE_BUSY;
568
569 /* Enable the noise wave generation for the selected DAC channel */
570 MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1) | (DAC_CR_MAMP1)) << (Channel & 0x10UL),
571 (DAC_CR_WAVE1_0 | Amplitude) << (Channel & 0x10UL));
572
573 /* Change DAC state */
574 hdac->State = HAL_DAC_STATE_READY;
575
576 /* Process unlocked */
577 __HAL_UNLOCK(hdac);
578
579 /* Return function status */
580 return HAL_OK;
581 }
582
583
584 /**
585 * @brief Set the specified data holding register value for dual DAC channel.
586 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
587 * the configuration information for the specified DAC.
588 * @param Alignment Specifies the data alignment for dual channel DAC.
589 * This parameter can be one of the following values:
590 * DAC_ALIGN_8B_R: 8bit right data alignment selected
591 * DAC_ALIGN_12B_L: 12bit left data alignment selected
592 * DAC_ALIGN_12B_R: 12bit right data alignment selected
593 * @param Data1 Data for DAC Channel1 to be loaded in the selected data holding register.
594 * @param Data2 Data for DAC Channel2 to be loaded in the selected data holding register.
595 * @note In dual mode, a unique register access is required to write in both
596 * DAC channels at the same time.
597 * @retval HAL status
598 */
HAL_DACEx_DualSetValue(DAC_HandleTypeDef * hdac,uint32_t Alignment,uint32_t Data1,uint32_t Data2)599 HAL_StatusTypeDef HAL_DACEx_DualSetValue(DAC_HandleTypeDef *hdac, uint32_t Alignment, uint32_t Data1, uint32_t Data2)
600 {
601 uint32_t data;
602 uint32_t tmp;
603
604 /* Check the DAC peripheral handle */
605 if (hdac == NULL)
606 {
607 return HAL_ERROR;
608 }
609
610 /* Check the parameters */
611 assert_param(IS_DAC_ALIGN(Alignment));
612 assert_param(IS_DAC_DATA(Data1));
613 assert_param(IS_DAC_DATA(Data2));
614
615 /* Calculate and set dual DAC data holding register value */
616 if (Alignment == DAC_ALIGN_8B_R)
617 {
618 data = ((uint32_t)Data2 << 8U) | Data1;
619 }
620 else
621 {
622 data = ((uint32_t)Data2 << 16U) | Data1;
623 }
624
625 tmp = (uint32_t)hdac->Instance;
626 tmp += DAC_DHR12RD_ALIGNMENT(Alignment);
627
628 /* Set the dual DAC selected data holding register */
629 *(__IO uint32_t *)tmp = data;
630
631 /* Return function status */
632 return HAL_OK;
633 }
634
635 /**
636 * @brief Conversion complete callback in non-blocking mode for Channel2.
637 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
638 * the configuration information for the specified DAC.
639 * @retval None
640 */
HAL_DACEx_ConvCpltCallbackCh2(DAC_HandleTypeDef * hdac)641 __weak void HAL_DACEx_ConvCpltCallbackCh2(DAC_HandleTypeDef *hdac)
642 {
643 /* Prevent unused argument(s) compilation warning */
644 UNUSED(hdac);
645
646 /* NOTE : This function should not be modified, when the callback is needed,
647 the HAL_DACEx_ConvCpltCallbackCh2 could be implemented in the user file
648 */
649 }
650
651 /**
652 * @brief Conversion half DMA transfer callback in non-blocking mode for Channel2.
653 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
654 * the configuration information for the specified DAC.
655 * @retval None
656 */
HAL_DACEx_ConvHalfCpltCallbackCh2(DAC_HandleTypeDef * hdac)657 __weak void HAL_DACEx_ConvHalfCpltCallbackCh2(DAC_HandleTypeDef *hdac)
658 {
659 /* Prevent unused argument(s) compilation warning */
660 UNUSED(hdac);
661
662 /* NOTE : This function should not be modified, when the callback is needed,
663 the HAL_DACEx_ConvHalfCpltCallbackCh2 could be implemented in the user file
664 */
665 }
666
667 /**
668 * @brief Error DAC callback for Channel2.
669 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
670 * the configuration information for the specified DAC.
671 * @retval None
672 */
HAL_DACEx_ErrorCallbackCh2(DAC_HandleTypeDef * hdac)673 __weak void HAL_DACEx_ErrorCallbackCh2(DAC_HandleTypeDef *hdac)
674 {
675 /* Prevent unused argument(s) compilation warning */
676 UNUSED(hdac);
677
678 /* NOTE : This function should not be modified, when the callback is needed,
679 the HAL_DACEx_ErrorCallbackCh2 could be implemented in the user file
680 */
681 }
682
683 /**
684 * @brief DMA underrun DAC callback for Channel2.
685 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
686 * the configuration information for the specified DAC.
687 * @retval None
688 */
HAL_DACEx_DMAUnderrunCallbackCh2(DAC_HandleTypeDef * hdac)689 __weak void HAL_DACEx_DMAUnderrunCallbackCh2(DAC_HandleTypeDef *hdac)
690 {
691 /* Prevent unused argument(s) compilation warning */
692 UNUSED(hdac);
693
694 /* NOTE : This function should not be modified, when the callback is needed,
695 the HAL_DACEx_DMAUnderrunCallbackCh2 could be implemented in the user file
696 */
697 }
698
699
700 /**
701 * @brief Run the self calibration of one DAC channel.
702 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
703 * the configuration information for the specified DAC.
704 * @param sConfig DAC channel configuration structure.
705 * @param Channel The selected DAC channel.
706 * This parameter can be one of the following values:
707 * @arg DAC_CHANNEL_1: DAC Channel1 selected
708 * @arg DAC_CHANNEL_2: DAC Channel2 selected
709 * @retval Updates DAC_TrimmingValue. , DAC_UserTrimming set to DAC_UserTrimming
710 * @retval HAL status
711 * @note Calibration runs about 7 ms.
712 */
HAL_DACEx_SelfCalibrate(DAC_HandleTypeDef * hdac,DAC_ChannelConfTypeDef * sConfig,uint32_t Channel)713 HAL_StatusTypeDef HAL_DACEx_SelfCalibrate(DAC_HandleTypeDef *hdac, DAC_ChannelConfTypeDef *sConfig, uint32_t Channel)
714 {
715 HAL_StatusTypeDef status = HAL_OK;
716
717 uint32_t trimmingvalue;
718 uint32_t delta;
719 __IO uint32_t wait_loop_index;
720
721 /* store/restore channel configuration structure purpose */
722 uint32_t oldmodeconfiguration;
723
724 /* Check the parameters */
725 assert_param(IS_DAC_CHANNEL(Channel));
726
727 /* Check the DAC handle allocation */
728 /* Check if DAC running */
729 if ((hdac == NULL) || (sConfig == NULL))
730 {
731 status = HAL_ERROR;
732 }
733 else if (hdac->State == HAL_DAC_STATE_BUSY)
734 {
735 status = HAL_ERROR;
736 }
737 else
738 {
739 /* Process locked */
740 __HAL_LOCK(hdac);
741
742 /* Store configuration */
743 oldmodeconfiguration = (hdac->Instance->MCR & (DAC_MCR_MODE1 << (Channel & 0x10UL)));
744
745 /* Disable the selected DAC channel */
746 CLEAR_BIT((hdac->Instance->CR), (DAC_CR_EN1 << (Channel & 0x10UL)));
747 /* Wait for ready bit to be de-asserted */
748 HAL_Delay(1);
749
750 /* Set mode in MCR for calibration */
751 MODIFY_REG(hdac->Instance->MCR, (DAC_MCR_MODE1 << (Channel & 0x10UL)), 0U);
752
753 /* Enable the selected DAC channel calibration */
754 /* i.e. set DAC_CR_CENx bit */
755 SET_BIT((hdac->Instance->CR), (DAC_CR_CEN1 << (Channel & 0x10UL)));
756
757 /* Init trimming counter */
758 /* Medium value */
759 trimmingvalue = 16UL;
760 delta = 8UL;
761 while (delta != 0UL)
762 {
763 /* Set candidate trimming */
764 MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (trimmingvalue << (Channel & 0x10UL)));
765
766 /* Wait minimum time needed between two calibration steps (OTRIM) */
767 /* Wait loop initialization and execution */
768 /* Note: Variable divided by 2 to compensate partially CPU processing cycles, scaling in us split to not exceed */
769 /* 32 bits register capacity and handle low frequency. */
770 wait_loop_index = ((DAC_DELAY_TRIM_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
771 while (wait_loop_index != 0UL)
772 {
773 wait_loop_index--;
774 }
775
776 if ((hdac->Instance->SR & (DAC_SR_CAL_FLAG1 << (Channel & 0x10UL))) == (DAC_SR_CAL_FLAG1 << (Channel & 0x10UL)))
777 {
778 /* DAC_SR_CAL_FLAGx is HIGH try higher trimming */
779 trimmingvalue -= delta;
780 }
781 else
782 {
783 /* DAC_SR_CAL_FLAGx is LOW try lower trimming */
784 trimmingvalue += delta;
785 }
786 delta >>= 1UL;
787 }
788
789 /* Still need to check if right calibration is current value or one step below */
790 /* Indeed the first value that causes the DAC_SR_CAL_FLAGx bit to change from 0 to 1 */
791 /* Set candidate trimming */
792 MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (trimmingvalue << (Channel & 0x10UL)));
793
794 /* Wait minimum time needed between two calibration steps (OTRIM) */
795 /* Wait loop initialization and execution */
796 /* Note: Variable divided by 2 to compensate partially CPU processing cycles, scaling in us split to not exceed */
797 /* 32 bits register capacity and handle low frequency. */
798 wait_loop_index = ((DAC_DELAY_TRIM_US / 10UL) * ((SystemCoreClock / (100000UL * 2UL)) + 1UL));
799 while (wait_loop_index != 0UL)
800 {
801 wait_loop_index--;
802 }
803
804 if ((hdac->Instance->SR & (DAC_SR_CAL_FLAG1 << (Channel & 0x10UL))) == 0UL)
805 {
806 /* Trimming is actually one value more */
807 trimmingvalue++;
808 /* Set right trimming */
809 MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (trimmingvalue << (Channel & 0x10UL)));
810 }
811
812 /* Disable the selected DAC channel calibration */
813 /* i.e. clear DAC_CR_CENx bit */
814 CLEAR_BIT((hdac->Instance->CR), (DAC_CR_CEN1 << (Channel & 0x10UL)));
815
816 sConfig->DAC_TrimmingValue = trimmingvalue;
817 sConfig->DAC_UserTrimming = DAC_TRIMMING_USER;
818
819 /* Restore configuration */
820 MODIFY_REG(hdac->Instance->MCR, (DAC_MCR_MODE1 << (Channel & 0x10UL)), oldmodeconfiguration);
821
822 /* Process unlocked */
823 __HAL_UNLOCK(hdac);
824 }
825
826 return status;
827 }
828
829 /**
830 * @brief Set the trimming mode and trimming value (user trimming mode applied).
831 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
832 * the configuration information for the specified DAC.
833 * @param sConfig DAC configuration structure updated with new DAC trimming value.
834 * @param Channel The selected DAC channel.
835 * This parameter can be one of the following values:
836 * @arg DAC_CHANNEL_1: DAC Channel1 selected
837 * @arg DAC_CHANNEL_2: DAC Channel2 selected
838 * @param NewTrimmingValue DAC new trimming value
839 * @retval HAL status
840 */
HAL_DACEx_SetUserTrimming(DAC_HandleTypeDef * hdac,DAC_ChannelConfTypeDef * sConfig,uint32_t Channel,uint32_t NewTrimmingValue)841 HAL_StatusTypeDef HAL_DACEx_SetUserTrimming(DAC_HandleTypeDef *hdac, DAC_ChannelConfTypeDef *sConfig, uint32_t Channel,
842 uint32_t NewTrimmingValue)
843 {
844 HAL_StatusTypeDef status = HAL_OK;
845
846 /* Check the parameters */
847 assert_param(IS_DAC_CHANNEL(Channel));
848 assert_param(IS_DAC_NEWTRIMMINGVALUE(NewTrimmingValue));
849
850 /* Check the DAC handle and channel configuration struct allocation */
851 if ((hdac == NULL) || (sConfig == NULL))
852 {
853 status = HAL_ERROR;
854 }
855 else
856 {
857 /* Process locked */
858 __HAL_LOCK(hdac);
859
860 /* Set new trimming */
861 MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (NewTrimmingValue << (Channel & 0x10UL)));
862
863 /* Update trimming mode */
864 sConfig->DAC_UserTrimming = DAC_TRIMMING_USER;
865 sConfig->DAC_TrimmingValue = NewTrimmingValue;
866
867 /* Process unlocked */
868 __HAL_UNLOCK(hdac);
869 }
870 return status;
871 }
872
873 /**
874 * @brief Return the DAC trimming value.
875 * @param hdac DAC handle
876 * @param Channel The selected DAC channel.
877 * This parameter can be one of the following values:
878 * @arg DAC_CHANNEL_1: DAC Channel1 selected
879 * @arg DAC_CHANNEL_2: DAC Channel2 selected
880 * @retval Trimming value : range: 0->31
881 *
882 */
HAL_DACEx_GetTrimOffset(const DAC_HandleTypeDef * hdac,uint32_t Channel)883 uint32_t HAL_DACEx_GetTrimOffset(const DAC_HandleTypeDef *hdac, uint32_t Channel)
884 {
885 /* Check the parameter */
886 assert_param(IS_DAC_CHANNEL(Channel));
887
888 /* Retrieve trimming */
889 return ((hdac->Instance->CCR & (DAC_CCR_OTRIM1 << (Channel & 0x10UL))) >> (Channel & 0x10UL));
890 }
891
892 /**
893 * @}
894 */
895
896 /** @defgroup DACEx_Exported_Functions_Group3 Peripheral Control functions
897 * @brief Extended Peripheral Control functions
898 *
899 @verbatim
900 ==============================================================================
901 ##### Peripheral Control functions #####
902 ==============================================================================
903 [..] This section provides functions allowing to:
904 (+) Set the specified data holding register value for DAC channel.
905
906 @endverbatim
907 * @{
908 */
909
910
911 /**
912 * @brief Return the last data output value of the selected DAC channel.
913 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
914 * the configuration information for the specified DAC.
915 * @retval The selected DAC channel data output value.
916 */
HAL_DACEx_DualGetValue(const DAC_HandleTypeDef * hdac)917 uint32_t HAL_DACEx_DualGetValue(const DAC_HandleTypeDef *hdac)
918 {
919 uint32_t tmp = 0UL;
920
921 tmp |= hdac->Instance->DOR1;
922
923 tmp |= hdac->Instance->DOR2 << 16UL;
924
925 /* Returns the DAC channel data output register value */
926 return tmp;
927 }
928
929
930 /**
931 * @}
932 */
933 /**
934 * @brief Set autonomous mode Configuration.
935 * @note The autonomous mode applies to the 2 channels of a DAC block (same for both channels)
936 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
937 * the configuration information for the specified DAC.
938 * @param sConfig pointer to Autonomous mode structure parameters.
939 * @retval HAL status
940 */
HAL_DACEx_SetConfigAutonomousMode(DAC_HandleTypeDef * hdac,const DAC_AutonomousModeConfTypeDef * sConfig)941 HAL_StatusTypeDef HAL_DACEx_SetConfigAutonomousMode(DAC_HandleTypeDef *hdac,
942 const DAC_AutonomousModeConfTypeDef *sConfig)
943 {
944 /* Check the DAC peripheral handle and autonomous mode configuration struct */
945 if ((hdac == NULL) || (sConfig == NULL))
946 {
947 return HAL_ERROR;
948 }
949
950 assert_param(IS_DAC_AUTONOMOUS(sConfig->AutonomousModeState));
951
952 if (hdac->State == HAL_DAC_STATE_READY)
953 {
954 /* Process Locked */
955 __HAL_LOCK(hdac);
956
957 hdac->State = HAL_DAC_STATE_BUSY;
958
959 /* NOTE: The set/reset of the bit automode in the AUTOCR
960 register is for both dac_channel1 and dac_channel2 */
961
962 /* Update the AUTOCR register */
963 MODIFY_REG(hdac->Instance->AUTOCR, DAC_AUTOCR_AUTOMODE, sConfig->AutonomousModeState);
964
965 /* Update the DAC state */
966 hdac->State = HAL_DAC_STATE_READY;
967
968 /* Process Unlocked */
969 __HAL_UNLOCK(hdac);
970
971 return HAL_OK;
972 }
973 else
974 {
975 return HAL_BUSY;
976 }
977 }
978
979 /**
980 * @brief Get autonomous mode Configuration.
981 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
982 * the configuration information for the specified DAC.
983 * @param sConfig pointer to Autonomous mode structure parameters.
984 * @retval HAL status
985 */
HAL_DACEx_GetConfigAutonomousMode(const DAC_HandleTypeDef * hdac,DAC_AutonomousModeConfTypeDef * sConfig)986 HAL_StatusTypeDef HAL_DACEx_GetConfigAutonomousMode(const DAC_HandleTypeDef *hdac,
987 DAC_AutonomousModeConfTypeDef *sConfig)
988 {
989 /* Check the DAC peripheral handle and autonomous mode configuration struct */
990 if ((hdac == NULL) || (sConfig == NULL))
991 {
992 return HAL_ERROR;
993 }
994
995 /* Fill Autonomous structure parameter */
996 sConfig->AutonomousModeState = READ_BIT(hdac->Instance->AUTOCR, DAC_AUTOCR_AUTOMODE);
997
998 return HAL_OK;
999 }
1000
1001 /**
1002 * @brief Clear autonomous mode Configuration.
1003 * @note The autonomous mode applies to the 2 channels of a DAC block (same for both channels)
1004 * @param hdac pointer to a DAC_HandleTypeDef structure that contains
1005 * the configuration information for the specified DAC.
1006 * @retval HAL status
1007 */
HAL_DACEx_ClearConfigAutonomousMode(DAC_HandleTypeDef * hdac)1008 HAL_StatusTypeDef HAL_DACEx_ClearConfigAutonomousMode(DAC_HandleTypeDef *hdac)
1009 {
1010 /* Check the DAC peripheral handle */
1011 if ((hdac == NULL))
1012 {
1013 return HAL_ERROR;
1014 }
1015
1016 if (hdac->State == HAL_DAC_STATE_READY)
1017 {
1018 /* Process Locked */
1019 __HAL_LOCK(hdac);
1020
1021 hdac->State = HAL_DAC_STATE_BUSY;
1022
1023 /* NOTE: The set/reset of the bit automode in the AUTOCR
1024 register is for both dac_channel1 and dac_channel2 */
1025
1026 /* Clear AUTOCR register */
1027 CLEAR_BIT(hdac->Instance->AUTOCR, DAC_AUTOCR_AUTOMODE);
1028
1029 hdac->State = HAL_DAC_STATE_READY;
1030
1031 /* Process Unlocked */
1032 __HAL_UNLOCK(hdac);
1033
1034 return HAL_OK;
1035 }
1036 else
1037 {
1038 return HAL_BUSY;
1039 }
1040 }
1041 /**
1042 * @}
1043 */
1044
1045 /* Private functions ---------------------------------------------------------*/
1046 /** @defgroup DACEx_Private_Functions DACEx private functions
1047 * @brief Extended private functions
1048 * @{
1049 */
1050
1051
1052 /**
1053 * @brief DMA conversion complete callback.
1054 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1055 * the configuration information for the specified DMA module.
1056 * @retval None
1057 */
DAC_DMAConvCpltCh2(DMA_HandleTypeDef * hdma)1058 void DAC_DMAConvCpltCh2(DMA_HandleTypeDef *hdma)
1059 {
1060 DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1061
1062 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
1063 hdac->ConvCpltCallbackCh2(hdac);
1064 #else
1065 HAL_DACEx_ConvCpltCallbackCh2(hdac);
1066 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
1067
1068 hdac->State = HAL_DAC_STATE_READY;
1069 }
1070
1071 /**
1072 * @brief DMA half transfer complete callback.
1073 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1074 * the configuration information for the specified DMA module.
1075 * @retval None
1076 */
DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef * hdma)1077 void DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef *hdma)
1078 {
1079 DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1080 /* Conversion complete callback */
1081 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
1082 hdac->ConvHalfCpltCallbackCh2(hdac);
1083 #else
1084 HAL_DACEx_ConvHalfCpltCallbackCh2(hdac);
1085 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
1086 }
1087
1088 /**
1089 * @brief DMA error callback.
1090 * @param hdma pointer to a DMA_HandleTypeDef structure that contains
1091 * the configuration information for the specified DMA module.
1092 * @retval None
1093 */
DAC_DMAErrorCh2(DMA_HandleTypeDef * hdma)1094 void DAC_DMAErrorCh2(DMA_HandleTypeDef *hdma)
1095 {
1096 DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
1097
1098 /* Set DAC error code to DMA error */
1099 hdac->ErrorCode |= HAL_DAC_ERROR_DMA;
1100
1101 #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1)
1102 hdac->ErrorCallbackCh2(hdac);
1103 #else
1104 HAL_DACEx_ErrorCallbackCh2(hdac);
1105 #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */
1106
1107 hdac->State = HAL_DAC_STATE_READY;
1108 }
1109
1110
1111 /**
1112 * @}
1113 */
1114
1115 /**
1116 * @}
1117 */
1118
1119 #endif /* DAC1 */
1120
1121 #endif /* HAL_DAC_MODULE_ENABLED */
1122
1123 /**
1124 * @}
1125 */
1126