/** ****************************************************************************** * @file stm32h7xx_hal_dac_ex.c * @author MCD Application Team * @brief Extended DAC HAL module driver. * This file provides firmware functions to manage the extended * functionalities of the DAC peripheral. * * @verbatim ============================================================================== ##### How to use this driver ##### ============================================================================== [..] *** Dual mode IO operation *** ============================== (+) Use HAL_DACEx_DualStart() to enable both channel and start conversion for dual mode operation. If software trigger is selected, using HAL_DACEx_DualStart() will start the conversion of the value previously set by HAL_DACEx_DualSetValue(). (+) Use HAL_DACEx_DualStop() to disable both channel and stop conversion for dual mode operation. (+) Use HAL_DACEx_DualStart_DMA() to enable both channel and start conversion for dual mode operation using DMA to feed DAC converters. First issued trigger will start the conversion of the value previously set by HAL_DACEx_DualSetValue(). The same callbacks that are used in single mode are called in dual mode to notify transfer completion (half complete or complete), errors or underrun. (+) Use HAL_DACEx_DualStop_DMA() to disable both channel and stop conversion for dual mode operation using DMA to feed DAC converters. (+) When Dual mode is enabled (i.e. DAC Channel1 and Channel2 are used simultaneously) : Use HAL_DACEx_DualGetValue() to get digital data to be converted and use HAL_DACEx_DualSetValue() to set digital value to converted simultaneously in Channel 1 and Channel 2. *** Signal generation operation *** =================================== (+) Use HAL_DACEx_TriangleWaveGenerate() to generate Triangle signal. (+) Use HAL_DACEx_NoiseWaveGenerate() to generate Noise signal. (+) HAL_DACEx_SelfCalibrate to calibrate one DAC channel. (+) HAL_DACEx_SetUserTrimming to set user trimming value. (+) HAL_DACEx_GetTrimOffset to retrieve trimming value (factory setting after reset, user setting if HAL_DACEx_SetUserTrimming have been used at least one time after reset). @endverbatim ****************************************************************************** * @attention * *

© Copyright (c) 2017 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "stm32h7xx_hal.h" /** @addtogroup STM32H7xx_HAL_Driver * @{ */ #ifdef HAL_DAC_MODULE_ENABLED #if defined(DAC1) || defined(DAC2) /** @defgroup DACEx DACEx * @brief DAC Extended HAL module driver * @{ */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ /* Exported functions --------------------------------------------------------*/ /** @defgroup DACEx_Exported_Functions DACEx Exported Functions * @{ */ /** @defgroup DACEx_Exported_Functions_Group2 IO operation functions * @brief Extended IO operation functions * @verbatim ============================================================================== ##### Extended features functions ##### ============================================================================== [..] This section provides functions allowing to: (+) Start conversion. (+) Stop conversion. (+) Start conversion and enable DMA transfer. (+) Stop conversion and disable DMA transfer. (+) Get result of conversion. (+) Get result of dual mode conversion. @endverbatim * @{ */ /** * @brief Enables DAC and starts conversion of both channels. * @param hdac pointer to a DAC_HandleTypeDef structure that contains * the configuration information for the specified DAC. * @retval HAL status */ HAL_StatusTypeDef HAL_DACEx_DualStart(DAC_HandleTypeDef *hdac) { uint32_t tmp_swtrig = 0UL; /* Process locked */ __HAL_LOCK(hdac); /* Change DAC state */ hdac->State = HAL_DAC_STATE_BUSY; /* Enable the Peripheral */ __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_1); __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_2); /* Check if software trigger enabled */ if ((hdac->Instance->CR & (DAC_CR_TEN1 | DAC_CR_TSEL1)) == DAC_CR_TEN1) { tmp_swtrig |= DAC_SWTRIGR_SWTRIG1; } if ((hdac->Instance->CR & (DAC_CR_TEN2 | DAC_CR_TSEL2)) == DAC_CR_TEN2) { tmp_swtrig |= DAC_SWTRIGR_SWTRIG2; } /* Enable the selected DAC software conversion*/ SET_BIT(hdac->Instance->SWTRIGR, tmp_swtrig); /* Change DAC state */ hdac->State = HAL_DAC_STATE_READY; /* Process unlocked */ __HAL_UNLOCK(hdac); /* Return function status */ return HAL_OK; } /** * @brief Disables DAC and stop conversion of both channels. * @param hdac pointer to a DAC_HandleTypeDef structure that contains * the configuration information for the specified DAC. * @retval HAL status */ HAL_StatusTypeDef HAL_DACEx_DualStop(DAC_HandleTypeDef *hdac) { /* Disable the Peripheral */ __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_1); __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_2); /* Change DAC state */ hdac->State = HAL_DAC_STATE_READY; /* Return function status */ return HAL_OK; } /** * @brief Enables DAC and starts conversion of both channel 1 and 2 of the same DAC. * @param hdac pointer to a DAC_HandleTypeDef structure that contains * the configuration information for the specified DAC. * @param Channel The DAC channel that will request data from DMA. * This parameter can be one of the following values: * @arg DAC_CHANNEL_1: DAC Channel1 selected * @arg DAC_CHANNEL_2: DAC Channel2 selected * @param pData The destination peripheral Buffer address. * @param Length The length of data to be transferred from memory to DAC peripheral * @param Alignment Specifies the data alignment for DAC channel. * This parameter can be one of the following values: * @arg DAC_ALIGN_8B_R: 8bit right data alignment selected * @arg DAC_ALIGN_12B_L: 12bit left data alignment selected * @arg DAC_ALIGN_12B_R: 12bit right data alignment selected * @retval HAL status */ HAL_StatusTypeDef HAL_DACEx_DualStart_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t *pData, uint32_t Length, uint32_t Alignment) { HAL_StatusTypeDef status; uint32_t tmpreg = 0UL; /* Check the parameters */ assert_param(IS_DAC_CHANNEL(Channel)); assert_param(IS_DAC_ALIGN(Alignment)); /* Process locked */ __HAL_LOCK(hdac); /* Change DAC state */ hdac->State = HAL_DAC_STATE_BUSY; if (Channel == DAC_CHANNEL_1) { /* Set the DMA transfer complete callback for channel1 */ hdac->DMA_Handle1->XferCpltCallback = DAC_DMAConvCpltCh1; /* Set the DMA half transfer complete callback for channel1 */ hdac->DMA_Handle1->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh1; /* Set the DMA error callback for channel1 */ hdac->DMA_Handle1->XferErrorCallback = DAC_DMAErrorCh1; /* Enable the selected DAC channel1 DMA request */ SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN1); } else { /* Set the DMA transfer complete callback for channel2 */ hdac->DMA_Handle2->XferCpltCallback = DAC_DMAConvCpltCh2; /* Set the DMA half transfer complete callback for channel2 */ hdac->DMA_Handle2->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh2; /* Set the DMA error callback for channel2 */ hdac->DMA_Handle2->XferErrorCallback = DAC_DMAErrorCh2; /* Enable the selected DAC channel2 DMA request */ SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN2); } switch (Alignment) { case DAC_ALIGN_12B_R: /* Get DHR12R1 address */ tmpreg = (uint32_t)&hdac->Instance->DHR12RD; break; case DAC_ALIGN_12B_L: /* Get DHR12L1 address */ tmpreg = (uint32_t)&hdac->Instance->DHR12LD; break; case DAC_ALIGN_8B_R: /* Get DHR8R1 address */ tmpreg = (uint32_t)&hdac->Instance->DHR8RD; break; default: break; } /* Enable the DMA channel */ if (Channel == DAC_CHANNEL_1) { /* Enable the DAC DMA underrun interrupt */ __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR1); /* Enable the DMA channel */ status = HAL_DMA_Start_IT(hdac->DMA_Handle1, (uint32_t)pData, tmpreg, Length); } else { /* Enable the DAC DMA underrun interrupt */ __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR2); /* Enable the DMA channel */ status = HAL_DMA_Start_IT(hdac->DMA_Handle2, (uint32_t)pData, tmpreg, Length); } /* Process Unlocked */ __HAL_UNLOCK(hdac); if (status == HAL_OK) { /* Enable the Peripheral */ __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_1); __HAL_DAC_ENABLE(hdac, DAC_CHANNEL_2); } else { hdac->ErrorCode |= HAL_DAC_ERROR_DMA; } /* Return function status */ return status; } /** * @brief Disables DAC and stop conversion both channel. * @param hdac pointer to a DAC_HandleTypeDef structure that contains * the configuration information for the specified DAC. * @param Channel The DAC channel that requests data from DMA. * This parameter can be one of the following values: * @arg DAC_CHANNEL_1: DAC Channel1 selected * @arg DAC_CHANNEL_2: DAC Channel2 selected * @retval HAL status */ HAL_StatusTypeDef HAL_DACEx_DualStop_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel) { HAL_StatusTypeDef status; /* Disable the selected DAC channel DMA request */ CLEAR_BIT(hdac->Instance->CR, DAC_CR_DMAEN2 | DAC_CR_DMAEN1); /* Disable the Peripheral */ __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_1); __HAL_DAC_DISABLE(hdac, DAC_CHANNEL_2); /* Disable the DMA channel */ /* Channel1 is used */ if (Channel == DAC_CHANNEL_1) { /* Disable the DMA channel */ status = HAL_DMA_Abort(hdac->DMA_Handle1); /* Disable the DAC DMA underrun interrupt */ __HAL_DAC_DISABLE_IT(hdac, DAC_IT_DMAUDR1); } else { /* Disable the DMA channel */ status = HAL_DMA_Abort(hdac->DMA_Handle2); /* Disable the DAC DMA underrun interrupt */ __HAL_DAC_DISABLE_IT(hdac, DAC_IT_DMAUDR2); } /* Check if DMA Channel effectively disabled */ if (status != HAL_OK) { /* Update DAC state machine to error */ hdac->State = HAL_DAC_STATE_ERROR; } else { /* Change DAC state */ hdac->State = HAL_DAC_STATE_READY; } /* Return function status */ return status; } /** * @brief Enable or disable the selected DAC channel wave generation. * @param hdac pointer to a DAC_HandleTypeDef structure that contains * the configuration information for the specified DAC. * @param Channel The selected DAC channel. * This parameter can be one of the following values: * @arg DAC_CHANNEL_1: DAC Channel1 selected * @arg DAC_CHANNEL_2: DAC Channel2 selected * @param Amplitude Select max triangle amplitude. * This parameter can be one of the following values: * @arg DAC_TRIANGLEAMPLITUDE_1: Select max triangle amplitude of 1 * @arg DAC_TRIANGLEAMPLITUDE_3: Select max triangle amplitude of 3 * @arg DAC_TRIANGLEAMPLITUDE_7: Select max triangle amplitude of 7 * @arg DAC_TRIANGLEAMPLITUDE_15: Select max triangle amplitude of 15 * @arg DAC_TRIANGLEAMPLITUDE_31: Select max triangle amplitude of 31 * @arg DAC_TRIANGLEAMPLITUDE_63: Select max triangle amplitude of 63 * @arg DAC_TRIANGLEAMPLITUDE_127: Select max triangle amplitude of 127 * @arg DAC_TRIANGLEAMPLITUDE_255: Select max triangle amplitude of 255 * @arg DAC_TRIANGLEAMPLITUDE_511: Select max triangle amplitude of 511 * @arg DAC_TRIANGLEAMPLITUDE_1023: Select max triangle amplitude of 1023 * @arg DAC_TRIANGLEAMPLITUDE_2047: Select max triangle amplitude of 2047 * @arg DAC_TRIANGLEAMPLITUDE_4095: Select max triangle amplitude of 4095 * @retval HAL status */ HAL_StatusTypeDef HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Amplitude) { /* Check the parameters */ assert_param(IS_DAC_CHANNEL(Channel)); assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude)); /* Process locked */ __HAL_LOCK(hdac); /* Change DAC state */ hdac->State = HAL_DAC_STATE_BUSY; /* Enable the triangle wave generation for the selected DAC channel */ MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1) | (DAC_CR_MAMP1)) << (Channel & 0x10UL), (DAC_CR_WAVE1_1 | Amplitude) << (Channel & 0x10UL)); /* Change DAC state */ hdac->State = HAL_DAC_STATE_READY; /* Process unlocked */ __HAL_UNLOCK(hdac); /* Return function status */ return HAL_OK; } /** * @brief Enable or disable the selected DAC channel wave generation. * @param hdac pointer to a DAC_HandleTypeDef structure that contains * the configuration information for the specified DAC. * @param Channel The selected DAC channel. * This parameter can be one of the following values: * @arg DAC_CHANNEL_1: DAC Channel1 selected * @arg DAC_CHANNEL_2: DAC Channel2 selected * @param Amplitude Unmask DAC channel LFSR for noise wave generation. * This parameter can be one of the following values: * @arg DAC_LFSRUNMASK_BIT0: Unmask DAC channel LFSR bit0 for noise wave generation * @arg DAC_LFSRUNMASK_BITS1_0: Unmask DAC channel LFSR bit[1:0] for noise wave generation * @arg DAC_LFSRUNMASK_BITS2_0: Unmask DAC channel LFSR bit[2:0] for noise wave generation * @arg DAC_LFSRUNMASK_BITS3_0: Unmask DAC channel LFSR bit[3:0] for noise wave generation * @arg DAC_LFSRUNMASK_BITS4_0: Unmask DAC channel LFSR bit[4:0] for noise wave generation * @arg DAC_LFSRUNMASK_BITS5_0: Unmask DAC channel LFSR bit[5:0] for noise wave generation * @arg DAC_LFSRUNMASK_BITS6_0: Unmask DAC channel LFSR bit[6:0] for noise wave generation * @arg DAC_LFSRUNMASK_BITS7_0: Unmask DAC channel LFSR bit[7:0] for noise wave generation * @arg DAC_LFSRUNMASK_BITS8_0: Unmask DAC channel LFSR bit[8:0] for noise wave generation * @arg DAC_LFSRUNMASK_BITS9_0: Unmask DAC channel LFSR bit[9:0] for noise wave generation * @arg DAC_LFSRUNMASK_BITS10_0: Unmask DAC channel LFSR bit[10:0] for noise wave generation * @arg DAC_LFSRUNMASK_BITS11_0: Unmask DAC channel LFSR bit[11:0] for noise wave generation * @retval HAL status */ HAL_StatusTypeDef HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Amplitude) { /* Check the parameters */ assert_param(IS_DAC_CHANNEL(Channel)); assert_param(IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude)); /* Process locked */ __HAL_LOCK(hdac); /* Change DAC state */ hdac->State = HAL_DAC_STATE_BUSY; /* Enable the noise wave generation for the selected DAC channel */ MODIFY_REG(hdac->Instance->CR, ((DAC_CR_WAVE1) | (DAC_CR_MAMP1)) << (Channel & 0x10UL), (DAC_CR_WAVE1_0 | Amplitude) << (Channel & 0x10UL)); /* Change DAC state */ hdac->State = HAL_DAC_STATE_READY; /* Process unlocked */ __HAL_UNLOCK(hdac); /* Return function status */ return HAL_OK; } /** * @brief Set the specified data holding register value for dual DAC channel. * @param hdac pointer to a DAC_HandleTypeDef structure that contains * the configuration information for the specified DAC. * @param Alignment Specifies the data alignment for dual channel DAC. * This parameter can be one of the following values: * DAC_ALIGN_8B_R: 8bit right data alignment selected * DAC_ALIGN_12B_L: 12bit left data alignment selected * DAC_ALIGN_12B_R: 12bit right data alignment selected * @param Data1 Data for DAC Channel1 to be loaded in the selected data holding register. * @param Data2 Data for DAC Channel2 to be loaded in the selected data holding register. * @note In dual mode, a unique register access is required to write in both * DAC channels at the same time. * @retval HAL status */ HAL_StatusTypeDef HAL_DACEx_DualSetValue(DAC_HandleTypeDef *hdac, uint32_t Alignment, uint32_t Data1, uint32_t Data2) { uint32_t data; uint32_t tmp; /* Check the parameters */ assert_param(IS_DAC_ALIGN(Alignment)); assert_param(IS_DAC_DATA(Data1)); assert_param(IS_DAC_DATA(Data2)); /* Calculate and set dual DAC data holding register value */ if (Alignment == DAC_ALIGN_8B_R) { data = ((uint32_t)Data2 << 8U) | Data1; } else { data = ((uint32_t)Data2 << 16U) | Data1; } tmp = (uint32_t)hdac->Instance; tmp += DAC_DHR12RD_ALIGNMENT(Alignment); /* Set the dual DAC selected data holding register */ *(__IO uint32_t *)tmp = data; /* Return function status */ return HAL_OK; } /** * @brief Conversion complete callback in non-blocking mode for Channel2. * @param hdac pointer to a DAC_HandleTypeDef structure that contains * the configuration information for the specified DAC. * @retval None */ __weak void HAL_DACEx_ConvCpltCallbackCh2(DAC_HandleTypeDef *hdac) { /* Prevent unused argument(s) compilation warning */ UNUSED(hdac); /* NOTE : This function should not be modified, when the callback is needed, the HAL_DACEx_ConvCpltCallbackCh2 could be implemented in the user file */ } /** * @brief Conversion half DMA transfer callback in non-blocking mode for Channel2. * @param hdac pointer to a DAC_HandleTypeDef structure that contains * the configuration information for the specified DAC. * @retval None */ __weak void HAL_DACEx_ConvHalfCpltCallbackCh2(DAC_HandleTypeDef *hdac) { /* Prevent unused argument(s) compilation warning */ UNUSED(hdac); /* NOTE : This function should not be modified, when the callback is needed, the HAL_DACEx_ConvHalfCpltCallbackCh2 could be implemented in the user file */ } /** * @brief Error DAC callback for Channel2. * @param hdac pointer to a DAC_HandleTypeDef structure that contains * the configuration information for the specified DAC. * @retval None */ __weak void HAL_DACEx_ErrorCallbackCh2(DAC_HandleTypeDef *hdac) { /* Prevent unused argument(s) compilation warning */ UNUSED(hdac); /* NOTE : This function should not be modified, when the callback is needed, the HAL_DACEx_ErrorCallbackCh2 could be implemented in the user file */ } /** * @brief DMA underrun DAC callback for Channel2. * @param hdac pointer to a DAC_HandleTypeDef structure that contains * the configuration information for the specified DAC. * @retval None */ __weak void HAL_DACEx_DMAUnderrunCallbackCh2(DAC_HandleTypeDef *hdac) { /* Prevent unused argument(s) compilation warning */ UNUSED(hdac); /* NOTE : This function should not be modified, when the callback is needed, the HAL_DACEx_DMAUnderrunCallbackCh2 could be implemented in the user file */ } /** * @brief Run the self calibration of one DAC channel. * @param hdac pointer to a DAC_HandleTypeDef structure that contains * the configuration information for the specified DAC. * @param sConfig DAC channel configuration structure. * @param Channel The selected DAC channel. * This parameter can be one of the following values: * @arg DAC_CHANNEL_1: DAC Channel1 selected * @arg DAC_CHANNEL_2: DAC Channel2 selected * @retval Updates DAC_TrimmingValue. , DAC_UserTrimming set to DAC_UserTrimming * @retval HAL status * @note Calibration runs about 7 ms. */ HAL_StatusTypeDef HAL_DACEx_SelfCalibrate(DAC_HandleTypeDef *hdac, DAC_ChannelConfTypeDef *sConfig, uint32_t Channel) { HAL_StatusTypeDef status = HAL_OK; __IO uint32_t tmp; uint32_t trimmingvalue; uint32_t delta; /* store/restore channel configuration structure purpose */ uint32_t oldmodeconfiguration; /* Check the parameters */ assert_param(IS_DAC_CHANNEL(Channel)); /* Check the DAC handle allocation */ /* Check if DAC running */ if (hdac == NULL) { status = HAL_ERROR; } else if (hdac->State == HAL_DAC_STATE_BUSY) { status = HAL_ERROR; } else { /* Process locked */ __HAL_LOCK(hdac); /* Store configuration */ oldmodeconfiguration = (hdac->Instance->MCR & (DAC_MCR_MODE1 << (Channel & 0x10UL))); /* Disable the selected DAC channel */ CLEAR_BIT((hdac->Instance->CR), (DAC_CR_EN1 << (Channel & 0x10UL))); /* Set mode in MCR for calibration */ MODIFY_REG(hdac->Instance->MCR, (DAC_MCR_MODE1 << (Channel & 0x10UL)), 0U); /* Set DAC Channel1 DHR register to the middle value */ tmp = (uint32_t)hdac->Instance; if (Channel == DAC_CHANNEL_1) { tmp += DAC_DHR12R1_ALIGNMENT(DAC_ALIGN_12B_R); } else { tmp += DAC_DHR12R2_ALIGNMENT(DAC_ALIGN_12B_R); } *(__IO uint32_t *) tmp = 0x0800UL; /* Enable the selected DAC channel calibration */ /* i.e. set DAC_CR_CENx bit */ SET_BIT((hdac->Instance->CR), (DAC_CR_CEN1 << (Channel & 0x10UL))); /* Init trimming counter */ /* Medium value */ trimmingvalue = 16UL; delta = 8UL; while (delta != 0UL) { /* Set candidate trimming */ MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (trimmingvalue << (Channel & 0x10UL))); /* tOFFTRIMmax delay x ms as per datasheet (electrical characteristics */ /* i.e. minimum time needed between two calibration steps */ HAL_Delay(1); if ((hdac->Instance->SR & (DAC_SR_CAL_FLAG1 << (Channel & 0x10UL))) == (DAC_SR_CAL_FLAG1 << (Channel & 0x10UL))) { /* DAC_SR_CAL_FLAGx is HIGH try higher trimming */ trimmingvalue -= delta; } else { /* DAC_SR_CAL_FLAGx is LOW try lower trimming */ trimmingvalue += delta; } delta >>= 1UL; } /* Still need to check if right calibration is current value or one step below */ /* Indeed the first value that causes the DAC_SR_CAL_FLAGx bit to change from 0 to 1 */ /* Set candidate trimming */ MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (trimmingvalue << (Channel & 0x10UL))); /* tOFFTRIMmax delay x ms as per datasheet (electrical characteristics */ /* i.e. minimum time needed between two calibration steps */ HAL_Delay(1U); if ((hdac->Instance->SR & (DAC_SR_CAL_FLAG1 << (Channel & 0x10UL))) == 0UL) { /* Trimming is actually one value more */ trimmingvalue++; /* Set right trimming */ MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (trimmingvalue << (Channel & 0x10UL))); } /* Disable the selected DAC channel calibration */ /* i.e. clear DAC_CR_CENx bit */ CLEAR_BIT((hdac->Instance->CR), (DAC_CR_CEN1 << (Channel & 0x10UL))); sConfig->DAC_TrimmingValue = trimmingvalue; sConfig->DAC_UserTrimming = DAC_TRIMMING_USER; /* Restore configuration */ MODIFY_REG(hdac->Instance->MCR, (DAC_MCR_MODE1 << (Channel & 0x10UL)), oldmodeconfiguration); /* Process unlocked */ __HAL_UNLOCK(hdac); } return status; } /** * @brief Set the trimming mode and trimming value (user trimming mode applied). * @param hdac pointer to a DAC_HandleTypeDef structure that contains * the configuration information for the specified DAC. * @param sConfig DAC configuration structure updated with new DAC trimming value. * @param Channel The selected DAC channel. * This parameter can be one of the following values: * @arg DAC_CHANNEL_1: DAC Channel1 selected * @arg DAC_CHANNEL_2: DAC Channel2 selected * @param NewTrimmingValue DAC new trimming value * @retval HAL status */ HAL_StatusTypeDef HAL_DACEx_SetUserTrimming(DAC_HandleTypeDef *hdac, DAC_ChannelConfTypeDef *sConfig, uint32_t Channel, uint32_t NewTrimmingValue) { HAL_StatusTypeDef status = HAL_OK; /* Check the parameters */ assert_param(IS_DAC_CHANNEL(Channel)); assert_param(IS_DAC_NEWTRIMMINGVALUE(NewTrimmingValue)); /* Check the DAC handle allocation */ if (hdac == NULL) { status = HAL_ERROR; } else { /* Process locked */ __HAL_LOCK(hdac); /* Set new trimming */ MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (NewTrimmingValue << (Channel & 0x10UL))); /* Update trimming mode */ sConfig->DAC_UserTrimming = DAC_TRIMMING_USER; sConfig->DAC_TrimmingValue = NewTrimmingValue; /* Process unlocked */ __HAL_UNLOCK(hdac); } return status; } /** * @brief Return the DAC trimming value. * @param hdac DAC handle * @param Channel The selected DAC channel. * This parameter can be one of the following values: * @arg DAC_CHANNEL_1: DAC Channel1 selected * @arg DAC_CHANNEL_2: DAC Channel2 selected * @retval Trimming value : range: 0->31 * */ uint32_t HAL_DACEx_GetTrimOffset(DAC_HandleTypeDef *hdac, uint32_t Channel) { /* Check the parameter */ assert_param(IS_DAC_CHANNEL(Channel)); /* Retrieve trimming */ return ((hdac->Instance->CCR & (DAC_CCR_OTRIM1 << (Channel & 0x10UL))) >> (Channel & 0x10UL)); } /** * @} */ /** @defgroup DACEx_Exported_Functions_Group3 Peripheral Control functions * @brief Extended Peripheral Control functions * @verbatim ============================================================================== ##### Peripheral Control functions ##### ============================================================================== [..] This section provides functions allowing to: (+) Set the specified data holding register value for DAC channel. @endverbatim * @{ */ /** * @brief Return the last data output value of the selected DAC channel. * @param hdac pointer to a DAC_HandleTypeDef structure that contains * the configuration information for the specified DAC. * @retval The selected DAC channel data output value. */ uint32_t HAL_DACEx_DualGetValue(DAC_HandleTypeDef *hdac) { uint32_t tmp = 0UL; tmp |= hdac->Instance->DOR1; tmp |= hdac->Instance->DOR2 << 16UL; /* Returns the DAC channel data output register value */ return tmp; } /** * @} */ /** * @} */ /* Private functions ---------------------------------------------------------*/ /** @defgroup DACEx_Private_Functions DACEx private functions * @brief Extended private functions * @{ */ /** * @brief DMA conversion complete callback. * @param hdma pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA module. * @retval None */ void DAC_DMAConvCpltCh2(DMA_HandleTypeDef *hdma) { DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1) hdac->ConvCpltCallbackCh2(hdac); #else HAL_DACEx_ConvCpltCallbackCh2(hdac); #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */ hdac->State = HAL_DAC_STATE_READY; } /** * @brief DMA half transfer complete callback. * @param hdma pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA module. * @retval None */ void DAC_DMAHalfConvCpltCh2(DMA_HandleTypeDef *hdma) { DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Conversion complete callback */ #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1) hdac->ConvHalfCpltCallbackCh2(hdac); #else HAL_DACEx_ConvHalfCpltCallbackCh2(hdac); #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */ } /** * @brief DMA error callback. * @param hdma pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA module. * @retval None */ void DAC_DMAErrorCh2(DMA_HandleTypeDef *hdma) { DAC_HandleTypeDef *hdac = (DAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Set DAC error code to DMA error */ hdac->ErrorCode |= HAL_DAC_ERROR_DMA; #if (USE_HAL_DAC_REGISTER_CALLBACKS == 1) hdac->ErrorCallbackCh2(hdac); #else HAL_DACEx_ErrorCallbackCh2(hdac); #endif /* USE_HAL_DAC_REGISTER_CALLBACKS */ hdac->State = HAL_DAC_STATE_READY; } /** * @} */ /** * @} */ #endif /* DAC1 || DAC2 */ #endif /* HAL_DAC_MODULE_ENABLED */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/