rt-thread-official/bsp/acm32/acm32f4xx-nucleo/libraries/HAL_Driver/Src/HAL_DAC.c

829 lines
35 KiB
C
Raw Normal View History

2021-09-22 17:14:47 +08:00
/*
******************************************************************************
* @file HAL_DAC.c
* @version V1.0.0
* @date 2020
* @brief DAC HAL module driver.
* This file provides firmware functions to manage the following
* functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (DAC).
* @ Initialization and de-initialization functions
* @ IO operation functions
* @ Peripheral Control functions
******************************************************************************
*/
#include "ACM32Fxx_HAL.h"
/*********************************************************************************
* Function : HAL_DAC_IRQHandler
* Description : This function uses the interruption of DMA underrun.
* Input : hdac : pointer to a DAC_HandleTypeDef structure that contains
* the configuration information for DAC module
* Output :
* Author : CWT Data : 2020<EFBFBD><EFBFBD>
**********************************************************************************/
void HAL_DAC_IRQHandler(DAC_HandleTypeDef *hdac)
{
if((hdac->Instance->SR&DAC_SR_DMAUDR1)==DAC_SR_DMAUDR1||(hdac->Instance->SR &DAC_SR_DMAUDR2)==DAC_SR_DMAUDR2)
{
//clear the DMA underrun
hdac->Instance->SR|=DAC_SR_DMAUDR1|DAC_SR_DMAUDR2;
}
}
/*********************************************************************************
* Function : HAL_DAC_MspInit
* Description : Initialize the DAC MSP.
* Input : hdac : pointer to a DAC_HandleTypeDef structure that contains
* the configuration information for DAC module
* Output :
* Author : CWT Data : 2020<EFBFBD><EFBFBD>
**********************************************************************************/
__weak void HAL_DAC_MspInit(DAC_HandleTypeDef *hdac)
{
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_DAC_MspInit can be implemented in the user file
*/
/* For Example */
if(hdac->Instance==DAC)
{
/* Enable DAC clock */
System_Module_Enable(EN_DAC);
GPIO_InitTypeDef GPIO_InitStructure;
/* Initialization GPIO */
/**DAC1 GPIO Configuration
PB1 ------> DAC_OUT1
PB0 ------> DAC_OUT2
*/
GPIO_InitStructure.Pin = GPIO_PIN_1|GPIO_PIN_0;
GPIO_InitStructure.Pull=GPIO_NOPULL;
GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Enable the DAC DMA underrun interrupt */
hdac->Instance->CR |= DAC_CR_DMAUDRIE1|DAC_CR_DMAUDRIE2;
NVIC_ClearPendingIRQ(DAC_IRQn);
NVIC_SetPriority(DAC_IRQn, 5);
NVIC_EnableIRQ(DAC_IRQn);
}
}
/*********************************************************************************
* Function : HAL_DAC_MspDeInit
* Description : DAC MSP De-Initialization.
* Input : hdac : pointer to a DAC_HandleTypeDef structure that contains
* the configuration information for DAC module
* Output :
* Author : CWT Data : 2020<EFBFBD><EFBFBD>
**********************************************************************************/
void HAL_DAC_MspDeInit(DAC_HandleTypeDef* hdac)
{
if(hdac->Instance==DAC)
{
/* USER CODE BEGIN DAC1_MspDeInit 0 */
/* USER CODE END DAC1_MspDeInit 0 */
/* Peripheral clock disable */
System_Module_Disable(EN_DAC);
/**DAC1 GPIO Configuration
PB1 ------> DAC_OUT1
PB0 ------> DAC_OUT2
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_0);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_1);
/* DAC1 DMA DeInit */
HAL_DMA_DeInit(hdac->DMA_Handle1);
HAL_DMA_DeInit(hdac->DMA_Handle2);
/* USER CODE BEGIN DAC1_MspDeInit 1 */
/* USER CODE END DAC1_MspDeInit 1 */
}
}
/*********************************************************************************
* Function : HAL_DAC_Init
* Description : Initializes the CAN peripheral according to the specified parameters in the DAC_HandleTypeDef..
* Input : hdac : pointer to a DAC_HandleTypeDef structure that contains
* the configuration information for DAC module
* Output : HAL status
* Author : CWT Data : 2020<EFBFBD><EFBFBD>
**********************************************************************************/
HAL_StatusTypeDef HAL_DAC_Init(DAC_HandleTypeDef *hdac)
{
uint8_t InitStatus = HAL_ERROR;
/* Check the parameters */
if(!IS_DAC_ALL_PERIPH(hdac->Instance)) return HAL_ERROR;
System_Module_Reset(RST_DAC);
HAL_DAC_MspInit(hdac);
return HAL_OK;
}
/*********************************************************************************
* Function : HAL_DAC_DeInit
* Description : Deinitialize the DAC peripheral registers to their default reset values.
* Input : hdac : pointer to a DAC_HandleTypeDef structure that contains
* the configuration information for DAC module
* Output : HAL status
* Author : CWT Data : 2020<EFBFBD><EFBFBD>
**********************************************************************************/
HAL_StatusTypeDef HAL_DAC_DeInit(DAC_HandleTypeDef* hdac)
{
/* Check DAC handle */
if (hdac == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
if(!IS_DAC_ALL_PERIPH(hdac->Instance)) return HAL_ERROR;
HAL_DAC_MspDeInit(hdac);
/* Return function status */
return HAL_OK;
}
/*********************************************************************************
* Function : HAL_DAC_ConfigChannel
* Description : Configures the selected DAC channel.
* Input : hdac : hdac pointer to a DAC_HandleTypeDef structure that contains
* the configuration information for the specified DAC.
* sConfig:DAC configuration structure
* Channel:This parameter can be one of the following values: @arg DAC_CHANNEL_1 @argDAC_CHANNEL_2
* Output : HAL status
* Author : CWT Data : 2020<EFBFBD><EFBFBD>
**********************************************************************************/
HAL_StatusTypeDef HAL_DAC_ConfigChannel(DAC_HandleTypeDef* hdac, DAC_ChannelConfTypeDef* sConfig, uint32_t Channel)
{
uint32_t tmpreg1, tmpreg2;
uint32_t tickstart = 0U;
uint32_t ConnectOnChipPeripheral=0U;
/* Check the DAC parameters */
if(!IS_DAC_ALL_PERIPH(hdac->Instance)) return HAL_ERROR;
if(!IS_DAC_TRIGGER(sConfig->DAC_Trigger)) return HAL_ERROR;
if(!IS_DAC_OUTPUT_BUFFER_STATE(sConfig->DAC_OutputBuffer)) return HAL_ERROR;
if(!IS_DAC_CHIP_CONNECTION(sConfig->DAC_ConnectOnChipPeripheral)) return HAL_ERROR;
if(!IS_DAC_TRIMMING(sConfig->DAC_UserTrimming)) return HAL_ERROR;
if ((sConfig->DAC_UserTrimming) == DAC_TRIMMING_USER)
{
if(!IS_DAC_TRIMMINGVALUE(sConfig->DAC_TrimmingValue)) return HAL_ERROR;
}
if(!IS_DAC_SAMPLEANDHOLD(sConfig->DAC_SampleAndHold)) return HAL_ERROR;
if ((sConfig->DAC_SampleAndHold) == DAC_SAMPLEANDHOLD_ENABLE)
{
if(!IS_DAC_SAMPLETIME(sConfig->DAC_SampleAndHoldConfig.DAC_SampleTime)) return HAL_ERROR;
if(!IS_DAC_HOLDTIME(sConfig->DAC_SampleAndHoldConfig.DAC_HoldTime)) return HAL_ERROR;
if(!IS_DAC_REFRESHTIME(sConfig->DAC_SampleAndHoldConfig.DAC_RefreshTime)) return HAL_ERROR;
}
if(!IS_DAC_CHANNEL(Channel)) return HAL_ERROR;
if (sConfig->DAC_SampleAndHold == DAC_SAMPLEANDHOLD_ENABLE)
/* Sample on old configuration */
{
/* SampleTime */
if (Channel == DAC_CHANNEL_1)
{
hdac->Instance->SHSR1 = sConfig->DAC_SampleAndHoldConfig.DAC_SampleTime;
}
else /* Channel 2 */
hdac->Instance->SHSR2 = sConfig->DAC_SampleAndHoldConfig.DAC_SampleTime;
/* HoldTime */
MODIFY_REG(hdac->Instance->SHHR, DAC_SHHR_THOLD1 << (Channel & 0x10UL), (sConfig->DAC_SampleAndHoldConfig.DAC_HoldTime) << (Channel & 0x10UL));
/* RefreshTime */
MODIFY_REG(hdac->Instance->SHRR, DAC_SHRR_TREFRESH1 << (Channel & 0x10UL), (sConfig->DAC_SampleAndHoldConfig.DAC_RefreshTime) << (Channel & 0x10UL));
}
if (sConfig->DAC_UserTrimming == DAC_TRIMMING_USER)
/* USER TRIMMING */
{
/* Get the DAC CCR value */
tmpreg1 = hdac->Instance->CCR;
/* Clear trimming value */
tmpreg1 &= ~(((uint32_t)(DAC_CCR_OTRIM1)) << (Channel & 0x10UL));
/* Configure for the selected trimming offset */
tmpreg2 = sConfig->DAC_TrimmingValue;
/* Calculate CCR register value depending on DAC_Channel */
tmpreg1 |= tmpreg2 << (Channel & 0x10UL);
/* Write to DAC CCR */
hdac->Instance->CCR = tmpreg1;
}
else
{
/* factory trimming in NVR,read to DAC_CCR */
uint32_t OTRIM=*(uint32_t *)(0x80248);
uint32_t OTRIM_high=(OTRIM&0xffff0000)>>16;
uint32_t OTRIM_low=(OTRIM&0xffff);
if (OTRIM_low==((~OTRIM_high)&0xffff))
{
tmpreg1=(OTRIM_low&0x1f)|(((OTRIM_low&0x3E0)>>5)<<16);
hdac->Instance->CCR = tmpreg1;
}
}
/* Get the DAC MCR value */
tmpreg1 = hdac->Instance->MCR;
/* Clear DAC_MCR_MODEx bits */
tmpreg1 &= ~(((uint32_t)(DAC_MCR_MODE1)) << (Channel & 0x10UL));
/* Configure for the selected DAC channel: mode, buffer output & on chip peripheral connect */
ConnectOnChipPeripheral=sConfig->DAC_ConnectOnChipPeripheral;
if((sConfig->DAC_SampleAndHold == DAC_SAMPLEANDHOLD_ENABLE)&&(sConfig->DAC_OutputBuffer==DAC_OUTPUTBUFFER_DISABLE))
{
ConnectOnChipPeripheral=(!ConnectOnChipPeripheral);
}
tmpreg2 = (sConfig->DAC_SampleAndHold | sConfig->DAC_OutputBuffer | ConnectOnChipPeripheral);
/* Calculate MCR register value depending on DAC_Channel */
tmpreg1 |= tmpreg2 << (Channel & 0x10UL);
/* Write to DAC MCR */
hdac->Instance->MCR = tmpreg1;
/* DAC in normal operating mode hence clear DAC_CR_CENx bit */
CLEAR_BIT(hdac->Instance->CR, DAC_CR_CEN1 << (Channel & 0x10UL));
/* Get the DAC CR value */
tmpreg1 = hdac->Instance->CR;
/* Clear TENx, TSELx, WAVEx and MAMPx bits */
tmpreg1 &= ~(((uint32_t)(DAC_CR_MAMP1 | DAC_CR_WAVE1 | DAC_CR_TSEL1 | DAC_CR_TEN1)) << (Channel & 0x10UL));
/* Configure for the selected DAC channel: trigger */
/* Set TSELx and TENx bits according to DAC_Trigger value */
tmpreg2 = sConfig->DAC_Trigger;
/* Calculate CR register value depending on DAC_Channel */
tmpreg1 |= tmpreg2 << (Channel & 0x10UL);
/* Write to DAC CR */
hdac->Instance->CR = tmpreg1;
/* Disable wave generation */
hdac->Instance->CR &= ~(DAC_CR_WAVE1 << (Channel & 0x10UL));
/* Return function status */
return HAL_OK;
}
/*********************************************************************************
* Function : HAL_DAC_Start
* Description : Enables DAC and starts conversion of channel.
* Input : hdac : hdac pointer to a DAC_HandleTypeDef structure that contains
* the configuration information for the specified DAC.
* Channel:This parameter can be one of the following values: @arg DAC_CHANNEL_1 @argDAC_CHANNEL_2
* Output : HAL status
* Author : CWT Data : 2020<EFBFBD><EFBFBD>
**********************************************************************************/
HAL_StatusTypeDef HAL_DAC_Start(DAC_HandleTypeDef *hdac, uint32_t Channel)
{
/* Check the parameters */
if(!IS_DAC_ALL_PERIPH(hdac->Instance)) return HAL_ERROR;
if(!IS_DAC_CHANNEL(Channel)) return HAL_ERROR;
uint32_t tmp1 = 0U, tmp2 = 0U;
if (Channel == DAC_CHANNEL_1)
{
hdac->Instance->CR|=DAC_CR_EN1;
tmp1 = hdac->Instance->CR & DAC_CR_TEN1;
tmp2 = hdac->Instance->CR & DAC_CR_TSEL1;
/* Check if software trigger enabled */
if((tmp1 == DAC_CR_TEN1) && (tmp2 == DAC_CR_TSEL1))
{
/* Enable the selected DAC software conversion */
hdac->Instance->SWTRIGR|=DAC_SWTRIGR_SWTRIG1;
}
}
else
{
hdac->Instance->CR|=DAC_CR_EN2;
tmp1 = hdac->Instance->CR & DAC_CR_TEN2;
tmp2 = hdac->Instance->CR & DAC_CR_TSEL2;
/* Check if software trigger enabled */
if((tmp1 == DAC_CR_TEN2) && (tmp2 == DAC_CR_TSEL2))
{
/* Enable the selected DAC software conversion */
hdac->Instance->SWTRIGR|=DAC_SWTRIGR_SWTRIG2;
}
}
/* Return function status */
return HAL_OK;
}
/*********************************************************************************
* Function : HAL_DAC_Stop
* Description : Disables DAC and stop conversion of channel.
* Input : hdac : hdac pointer to a DAC_HandleTypeDef structure that contains
* the configuration information for the specified DAC.
* Channel:This parameter can be one of the following values: @arg DAC_CHANNEL_1 @argDAC_CHANNEL_2
* Output : HAL status
* Author : CWT Data : 2020<EFBFBD><EFBFBD>
**********************************************************************************/
HAL_StatusTypeDef HAL_DAC_Stop(DAC_HandleTypeDef* hdac, uint32_t Channel)
{
/* Check the parameters */
if(!IS_DAC_ALL_PERIPH(hdac->Instance)) return HAL_ERROR;
if(!IS_DAC_CHANNEL(Channel)) return HAL_ERROR;
/* Disable the Peripheral */
if (Channel == DAC_CHANNEL_1)
{
hdac->Instance->CR&=~DAC_CR_EN1;
}
else
{
hdac->Instance->CR&=~DAC_CR_EN2;
}
/* Return function status */
return HAL_OK;
}
/*********************************************************************************
* Function : HAL_DAC_Start_DMA
* Description : Enables DAC and starts conversion of channel.
* Input : hdac : hdac pointer to a DAC_HandleTypeDef structure that contains
* the configuration information for the specified DAC.
* Channel:This parameter can be one of the following values: @arg DAC_CHANNEL_1 @argDAC_CHANNEL_2 @arg DAC_CHANNEL_Dual
* pData: The destination peripheral Buffer address.
* Length: The length of data to be transferred from memory to DAC peripheral
* Alignment: Specifies the data alignment for DAC channel.This parameter can be one of the following values:
@arg DAC_ALIGN_8B_R @arg DAC_ALIGN_12B_L @arg DAC_ALIGN_12B_R
* Output : HAL status
* Author : CWT Data : 2020<EFBFBD><EFBFBD>
**********************************************************************************/
HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t *pData, uint32_t Length, uint32_t Alignment)
{
HAL_StatusTypeDef status;
uint32_t DstAddr = 0U;
/* Check the parameters */
if(!IS_DAC_ALL_PERIPH(hdac->Instance)) return HAL_ERROR;
if(!IS_DAC_CHANNEL(Channel)) return HAL_ERROR;
if(!IS_DAC_ALIGN(Alignment)) return HAL_ERROR;
if (Channel == DAC_CHANNEL_1)
{
/* Enable the DAC DMA underrun interrupt */
/* Enable the selected DAC channel2 DMA request */
hdac->Instance->CR |= DAC_CR_EN1|DAC_CR_DMAEN1|DAC_CR_DMAUDRIE1;
/* Case of use of channel 1 */
switch (Alignment)
{
case DAC_ALIGN_12B_R:
/* Get DHR12R1 address */
DstAddr = (uint32_t)&hdac->Instance->DHR12R1;
break;
case DAC_ALIGN_12B_L:
/* Get DHR12L1 address */
DstAddr = (uint32_t)&hdac->Instance->DHR12L1;
break;
case DAC_ALIGN_8B_R:
/* Get DHR8R1 address */
DstAddr = (uint32_t)&hdac->Instance->DHR8R1;
break;
default:
break;
}
status = HAL_DMA_Start_IT(hdac->DMA_Handle1, (uint32_t)pData, DstAddr, Length);
}
else if(Channel == DAC_CHANNEL_2)
{
/* Enable the DAC DMA underrun interrupt */
/* Enable the selected DAC channel2 DMA request */
hdac->Instance->CR |= DAC_CR_EN2|DAC_CR_DMAEN2|DAC_CR_DMAUDRIE2;
/* Case of use of channel 1 */
switch (Alignment)
{
case DAC_ALIGN_12B_R:
/* Get DHR12R1 address */
DstAddr = (uint32_t)&hdac->Instance->DHR12R2;
break;
case DAC_ALIGN_12B_L:
/* Get DHR12L1 address */
DstAddr = (uint32_t)&hdac->Instance->DHR12L2;
break;
case DAC_ALIGN_8B_R:
/* Get DHR8R1 address */
DstAddr = (uint32_t)&hdac->Instance->DHR8R2;
break;
default:
break;
}
status = HAL_DMA_Start_IT(hdac->DMA_Handle2, (uint32_t)pData, DstAddr, Length);
}
else/* DualChannel */
{
hdac->Instance->CR |= DAC_CR_EN1|DAC_CR_DMAEN1|DAC_CR_DMAUDRIE1|DAC_CR_EN2 ;
/* Case of use of channel_1 DMA change two DAC channel */
switch (Alignment)
{
case DAC_ALIGN_12B_R:
/* Get DHR12R1 address */
DstAddr = (uint32_t)&hdac->Instance->DHR12RD;
break;
case DAC_ALIGN_12B_L:
/* Get DHR12L1 address */
DstAddr = (uint32_t)&hdac->Instance->DHR12LD;
break;
case DAC_ALIGN_8B_R:
/* Get DHR8R1 address */
DstAddr = (uint32_t)&hdac->Instance->DHR8RD;
break;
default:
break;
}
status = HAL_DMA_Start_IT(hdac->DMA_Handle1, (uint32_t)pData, DstAddr, Length);
}
/* Return function status */
return status;
}
/*********************************************************************************
* Function : HAL_DAC_Stop_DMA
* Description : Disables DAC and stop conversion of channel.
* Input : hdac : hdac pointer to a DAC_HandleTypeDef structure that contains
* the configuration information for the specified DAC.
* Channel:This parameter can be one of the following values: @arg DAC_CHANNEL_1 @argDAC_CHANNEL_2 @arg DAC_CHANNEL_Dual
* Output : HAL status
* Author : CWT Data : 2020<EFBFBD><EFBFBD>
**********************************************************************************/
HAL_StatusTypeDef HAL_DAC_Stop_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel)
{
HAL_StatusTypeDef status = HAL_OK;
/* Check the parameters */
if(!IS_DAC_ALL_PERIPH(hdac->Instance)) return HAL_ERROR;
if(!IS_DAC_CHANNEL(Channel)) return HAL_ERROR;
/* Disable the selected DAC channel DMA request */
/* Disable the DMA Channel */
/* Channel1 is used */
if(Channel == DAC_CHANNEL_1)
{
hdac->Instance->CR &= ~DAC_CR_DMAEN1;
/* Disable the Peripheral */
hdac->Instance->CR&=~DAC_CR_EN1;
status = HAL_DMA_Abort(hdac->DMA_Handle1);
}
else if(Channel == DAC_CHANNEL_2) /* Channel2 is used for */
{
hdac->Instance->CR &= ~DAC_CR_DMAEN2;
hdac->Instance->CR&=~DAC_CR_EN2;
status = HAL_DMA_Abort(hdac->DMA_Handle2);
}
else
{
hdac->Instance->CR &= ~DAC_CR_DMAEN1;
hdac->Instance->CR &= ~DAC_CR_DMAEN2;
/* Disable the Peripheral */
hdac->Instance->CR&=~DAC_CR_EN1;
hdac->Instance->CR&=~DAC_CR_EN2;
status = HAL_DMA_Abort(hdac->DMA_Handle1)|HAL_DMA_Abort(hdac->DMA_Handle2);
}
/* Return function status */
return status;
}
/*********************************************************************************
* Function : HAL_DAC_SetChannelValue
* Description : Set the specified data holding register value for DAC channel.
* Input : hdac : hdac pointer to a DAC_HandleTypeDef structure that contains
* the configuration information for the specified DAC.
* Channel:This parameter can be one of the following values: @arg DAC_CHANNEL_1 @argDAC_CHANNEL_2
* Alignment: Specifies the data alignment for DAC channel.This parameter can be one of the following values:
* @arg DAC_ALIGN_8B_R @arg DAC_ALIGN_12B_L @arg DAC_ALIGN_12B_R
* Data:The destination peripheral Buffer address.
* Output : HAL status
* Author : CWT Data : 2020<EFBFBD><EFBFBD>
**********************************************************************************/
HAL_StatusTypeDef HAL_DAC_SetValue(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data)
{
__IO uint32_t tmp = 0;
/* Check the parameters */
if(!IS_DAC_ALL_PERIPH(hdac->Instance)) return HAL_ERROR;
if(!IS_DAC_CHANNEL(Channel)) return HAL_ERROR;
if(!IS_DAC_ALIGN(Alignment)) return HAL_ERROR;
tmp = (uint32_t)hdac->Instance;
if (Channel == DAC_CHANNEL_1)
{
tmp += DAC_DHR12R1_ALIGNMENT(Alignment);
}
else
{
tmp += DAC_DHR12R2_ALIGNMENT(Alignment);
}
/* Calculate and set dual DAC data holding register value */
if (Alignment == DAC_ALIGN_12B_L)
{
Data = (uint32_t)Data << 4;
}
/* Set the DAC channel selected data holding register */
*(__IO uint32_t *) tmp = Data;
/* Return function status */
return HAL_OK;
}
/*********************************************************************************
* Function : HAL_DACEx_DualSetValue
* Description : Set the specified data holding register value for dual DAC channel.
* Input : hdac : hdac pointer to a DAC_HandleTypeDef structure that contains
* the configuration information for the specified DAC.
* Alignment: Specifies the data alignment for DAC channel.This parameter can be one of the following values:
* @arg DAC_ALIGN_8B_R @arg DAC_ALIGN_12B_L @arg DAC_ALIGN_12B_R
* Datax:The destination peripheral Buffer address.
* Output : HAL status
* Author : CWT Data : 2020<EFBFBD><EFBFBD>
**********************************************************************************/
HAL_StatusTypeDef HAL_DACEx_DualSetValue(DAC_HandleTypeDef *hdac, uint32_t Alignment, uint32_t Data1, uint32_t Data2)
{
uint32_t data, tmp;
/* Check the parameters */
if(!IS_DAC_ALL_PERIPH(hdac->Instance)) return HAL_ERROR;
if(!IS_DAC_ALIGN(Alignment)) return HAL_ERROR;
/* Calculate and set dual DAC data holding register value */
if (Alignment == DAC_ALIGN_12B_L)
{
data = ((uint32_t)Data2 << 20U) | (Data1<<4);
}
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;
}
/*********************************************************************************
* Function : HAL_DAC_GetValue
* Description : Returns the last data output value of the selected DAC channel.
* Input : hdac : hdac pointer to a DAC_HandleTypeDef structure that contains
* the configuration information for the specified DAC.
* Channel:This parameter can be one of the following values: @arg DAC_CHANNEL_1 @arg DAC_CHANNEL_2
* Output : The selected DAC channel data output value.
* Author : CWT Data : 2020<EFBFBD><EFBFBD>
**********************************************************************************/
uint32_t HAL_DAC_GetValue(DAC_HandleTypeDef* hdac, uint32_t Channel)
{
/* Check the parameters */
if(!IS_DAC_ALL_PERIPH(hdac->Instance)) return HAL_ERROR;
if(!IS_DAC_CHANNEL(Channel)) return HAL_ERROR;
/* Returns the DAC channel data output register value */
if(Channel == DAC_CHANNEL_1)
{
return hdac->Instance->DOR1;
}
else
{
return hdac->Instance->DOR2;
}
}
/*********************************************************************************
* Function : HAL_DACEx_DualGetValue
* Description : Return the last data output value of the selected DAC channel.
* Input : hdac : hdac pointer to a DAC_HandleTypeDef structure that contains
* the configuration information for the specified DAC.
* Output : The selected DAC channel data output value.
* Author : CWT Data : 2020<EFBFBD><EFBFBD>
**********************************************************************************/
uint32_t HAL_DACEx_DualGetValue(DAC_HandleTypeDef *hdac)
{
/* Check the parameters */
if(!IS_DAC_ALL_PERIPH(hdac->Instance)) return HAL_ERROR;
uint32_t tmp = 0U;
tmp |= hdac->Instance->DOR1;
tmp |= hdac->Instance->DOR2 << 16U;
/* Returns the DAC channel data output register value */
return tmp;
}
/*********************************************************************************
* Function :HAL_DACEx_TriangleWaveGenerate
* Description : Enable or disable the selected DAC channel wave generation.
* Input : hdac : hdac pointer to a DAC_HandleTypeDef structure that contains
* the configuration information for the specified DAC.
* 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
* Amplitude: 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
* Author : CWT Data : 2020<EFBFBD><EFBFBD>
**********************************************************************************/
HAL_StatusTypeDef HAL_DACEx_TriangleWaveGenerate(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Amplitude)
{
/* Check the parameters */
if(!IS_DAC_ALL_PERIPH(hdac->Instance)) return HAL_ERROR;
if(!IS_DAC_CHANNEL(Channel)) return HAL_ERROR;
if(!IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude)) return HAL_ERROR;
/* 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));
/* Return function status */
return HAL_OK;
}
/*********************************************************************************
* Function : HAL_DACEx_NoiseWaveGenerate
* Description : Enable or disable the selected DAC channel wave generation
* Input : hdac : hdac pointer to a DAC_HandleTypeDef structure that contains
* the configuration information for the specified DAC.
* 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
* Amplitude: 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
* Output : HAL status
* Author : CWT Data : 2020<EFBFBD><EFBFBD>
**********************************************************************************/
HAL_StatusTypeDef HAL_DACEx_NoiseWaveGenerate(DAC_HandleTypeDef *hdac, uint32_t Channel, uint32_t Amplitude)
{
/* Check the parameters */
if(!IS_DAC_ALL_PERIPH(hdac->Instance)) return HAL_ERROR;
if(!IS_DAC_CHANNEL(Channel)) return HAL_ERROR;
if(!IS_DAC_LFSR_UNMASK_TRIANGLE_AMPLITUDE(Amplitude)) return HAL_ERROR;
/* 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));
/* Return function status */
return HAL_OK;
}
/*********************************************************************************
* Function : HAL_DACEx_SelfCalibrate
* Description : SRun the self calibration of one DAC channel.
* Input : hdac : hdac pointer to a DAC_HandleTypeDef structure that contains
* the configuration information for the specified DAC.
* sConfig:sConfig DAC channel configuration structure
* 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
* Output : HAL status
* Author : CWT Data : 2020<EFBFBD><EFBFBD>
**********************************************************************************/
HAL_StatusTypeDef HAL_DACEx_SelfCalibrate(DAC_HandleTypeDef *hdac, DAC_ChannelConfTypeDef *sConfig, uint32_t Channel)
{
/* Check the parameters */
if(!IS_DAC_ALL_PERIPH(hdac->Instance)) return HAL_ERROR;
if(!IS_DAC_CHANNEL(Channel)) return HAL_ERROR;
HAL_StatusTypeDef status = HAL_OK;
__IO uint32_t tmp;
uint32_t trimmingvalue;
uint32_t laststatus=0;
uint32_t nowstatus=0;
SET_BIT((hdac->Instance->CR), (DAC_CR_EN1 << (Channel & 0x10UL)));
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 = 0x0800U;
/* 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:0-31(0x1f)*/
for(trimmingvalue=0;trimmingvalue<32;trimmingvalue++)
{
/* Set candidate trimming */
MODIFY_REG(hdac->Instance->CCR, (DAC_CCR_OTRIM1 << (Channel & 0x10UL)), (trimmingvalue << (Channel & 0x10UL)));
System_Delay_MS(1);
laststatus=nowstatus;
nowstatus=(hdac->Instance->SR & (DAC_SR_CAL_FLAG1 << (Channel & 0x10UL)))>>(DAC_SR_CAL_FLAG1_Pos +Channel);
/* tOFFTRIMmax delay x ms as per datasheet (electrical characteristics */
/* i.e. minimum time needed between two calibration steps */
if (nowstatus==1&&laststatus==0)
{
break;
}
}
/* Disable the selected DAC channel calibration */
/* i.e. clear DAC_CR_CENx bit */
CLEAR_BIT((hdac->Instance->CR), (DAC_CR_CEN1 << (Channel & 0x10UL)));
/* Disable the selected DAC channel */
CLEAR_BIT((hdac->Instance->CR), (DAC_CR_EN1 << (Channel & 0x10UL)));
sConfig->DAC_TrimmingValue = trimmingvalue;
sConfig->DAC_UserTrimming = DAC_TRIMMING_USER;
return status;
}
/*********************************************************************************
* Function : HAL_DACEx_SetUserTrimming
* Description : Set the trimming mode and trimming value (user trimming mode applied).
* Input : hdac : hdac pointer to a DAC_HandleTypeDef structure that contains
* the configuration information for the specified DAC.
* sConfig:sConfig DAC channel configuration structure
* 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
* NewTrimmingValue: DAC new trimming value
* Output : HAL status
* Author : CWT Data : 2020<EFBFBD><EFBFBD>
**********************************************************************************/
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 */
if(!IS_DAC_ALL_PERIPH(hdac->Instance)) return HAL_ERROR;
if(!IS_DAC_CHANNEL(Channel)) return HAL_ERROR;
if(!IS_DAC_Calibration_TRIM(NewTrimmingValue)) return HAL_ERROR;
/* Check the DAC handle allocation */
if (hdac == NULL)
{
status = HAL_ERROR;
}
else
{
/* 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;
}
return status;
}
/*********************************************************************************
* Function : HAL_DACEx_GetTrimOffset
* Description : Return the DAC trimming value.
* Input : hdac : hdac pointer to a DAC_HandleTypeDef structure that contains
* the configuration information for the specified DAC.
* 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
* Output : Trimming value : range: 0->31
* Author : CWT Data : 2020<EFBFBD><EFBFBD>
**********************************************************************************/
uint32_t HAL_DACEx_GetTrimOffset(DAC_HandleTypeDef *hdac, uint32_t Channel)
{
/* Check the parameters */
if(!IS_DAC_ALL_PERIPH(hdac->Instance)) return HAL_ERROR;
if(!IS_DAC_CHANNEL(Channel)) return HAL_ERROR;
/* Retrieve trimming */
return ((hdac->Instance->CCR & (DAC_CCR_OTRIM1 << (Channel & 0x10UL))) >> (Channel & 0x10UL));
}