914 lines
35 KiB
C
914 lines
35 KiB
C
/*
|
||
******************************************************************************
|
||
* @file HAL_ADC.c
|
||
* @version V1.0.0
|
||
* @date 2020
|
||
* @brief ADC HAL module driver.
|
||
* This file provides firmware functions to manage the following
|
||
* functionalities of the Analog to Digital Converter (ADC) peripheral:
|
||
* @ Initialization functions
|
||
* @ IO operation functions
|
||
******************************************************************************
|
||
*/
|
||
#include "ACM32Fxx_HAL.h"
|
||
|
||
extern ADC_HandleTypeDef ADC_Handle;
|
||
|
||
/************************************************************************
|
||
* function : HAL_ADC_IRQHandler
|
||
* Description: This function handles SPI interrupt request.
|
||
* input : hadc : pointer to a ADC_HandleTypeDef structure that contains
|
||
* the configuration information for ADC module
|
||
************************************************************************/
|
||
__weak void HAL_ADC_IRQHandler(ADC_HandleTypeDef *hadc)
|
||
{
|
||
__IO uint32_t Status;
|
||
|
||
/* Check the parameters */
|
||
if(!IS_ADC_ALL_INSTANCE(hadc->Instance)) return;
|
||
if(!IS_ADC_ALL_CONCONVMODE(hadc->Init.ConConvMode)) return;
|
||
|
||
Status = hadc->Instance->SR;
|
||
/************ Check End of Conversion flag for injected ************/
|
||
if(__HAL_ADC_GET_IT_SOURCE(hadc, ADC_IE_JEOCIE))
|
||
{
|
||
if((Status & ADC_SR_JEOC) == ADC_SR_JEOC)
|
||
{
|
||
if(__HAL_ADC_CHECK_TRIG_INJECTED(hadc, ADC_SOFTWARE_START) ||
|
||
((__HAL_ADC_CHECK_TRIG_REGULAR(hadc, ADC_SOFTWARE_START)) &&
|
||
(hadc->Init.ConConvMode == 0)))
|
||
{
|
||
/* Disable ADC end of conversion interrupt on group injected */
|
||
__HAL_ADC_DISABLE_IT(hadc, ADC_IE_JEOCIE);
|
||
|
||
}
|
||
|
||
/* Conversion complete callback */
|
||
if (NULL != hadc->InjectedConvCpltCallback)
|
||
hadc->InjectedConvCpltCallback(hadc);
|
||
|
||
/* Clear injected group conversion flag */
|
||
__HAL_ADC_CLEAR_FLAG(hadc, ADC_SR_JEOC);
|
||
}
|
||
}
|
||
|
||
/************ Check Conversion flag for regular group ************/
|
||
if(__HAL_ADC_GET_IT_SOURCE(hadc, ADC_IE_EOCIE))
|
||
{
|
||
if((Status & ADC_SR_EOC) == ADC_SR_EOC)
|
||
{
|
||
/* Conversion complete callback */
|
||
if (NULL != hadc->ConvCpltCallback)
|
||
hadc->ConvCpltCallback(hadc);
|
||
|
||
/* Clear conversion flag */
|
||
__HAL_ADC_CLEAR_FLAG(hadc, ADC_SR_EOC);
|
||
}
|
||
}
|
||
|
||
/************ Check Analog watchdog flags ************/
|
||
if(__HAL_ADC_GET_IT_SOURCE(hadc, ADC_IE_AWDIE))
|
||
{
|
||
if((Status & ADC_SR_AWD) == ADC_SR_AWD)
|
||
{
|
||
/* Level out of window callback */
|
||
if (NULL != hadc->LevelOutOfWindowCallback)
|
||
hadc->LevelOutOfWindowCallback(hadc);
|
||
|
||
/* Clear the ADC analog watchdog flag */
|
||
__HAL_ADC_CLEAR_FLAG(hadc, ADC_SR_AWD);
|
||
}
|
||
}
|
||
|
||
/************ Check End of Conversion flag for regular group ************/
|
||
if(__HAL_ADC_GET_IT_SOURCE(hadc, ADC_IE_EOGIE))
|
||
{
|
||
if((Status & ADC_SR_EOG) == ADC_SR_EOG)
|
||
{
|
||
if((__HAL_ADC_CHECK_TRIG_REGULAR(hadc, ADC_SOFTWARE_START)) &&
|
||
(hadc->Init.ConConvMode == 0))
|
||
{
|
||
/* Disable ADC end of conversion interrupt on group regular */
|
||
__HAL_ADC_DISABLE_IT(hadc, ADC_IE_EOGIE);
|
||
}
|
||
|
||
/* Conversion complete callback */
|
||
if (NULL != hadc->GroupCpltCallback)
|
||
hadc->GroupCpltCallback(hadc);
|
||
|
||
/* Clear regular group conversion flag */
|
||
__HAL_ADC_CLEAR_FLAG(hadc, ADC_SR_EOG);
|
||
}
|
||
}
|
||
}
|
||
|
||
/************************************************************************
|
||
* function : HAL_ADC_MspInit
|
||
* Description:
|
||
* input : hadc : pointer to a ADC_HandleTypeDef structure that contains
|
||
* the configuration information for ADC module
|
||
* return : none
|
||
************************************************************************/
|
||
__weak void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
|
||
{
|
||
uint32_t i;
|
||
uint32_t ADC_Pin_Map[][3] =
|
||
{
|
||
{ ADC_CHANNEL_0_EN, GPIOC, GPIO_PIN_5 },
|
||
{ ADC_CHANNEL_1_EN, GPIOA, GPIO_PIN_7 },
|
||
{ ADC_CHANNEL_2_EN, GPIOA, GPIO_PIN_5 },
|
||
{ ADC_CHANNEL_3_EN, GPIOA, GPIO_PIN_3 },
|
||
{ ADC_CHANNEL_4_EN, GPIOC, GPIO_PIN_3 },
|
||
{ ADC_CHANNEL_5_EN, GPIOC, GPIO_PIN_1 },
|
||
{ ADC_CHANNEL_6_EN, GPIOA, GPIO_PIN_0 },
|
||
{ ADC_CHANNEL_8_EN, GPIOC, GPIO_PIN_4 },
|
||
{ ADC_CHANNEL_9_EN, GPIOA, GPIO_PIN_6 },
|
||
{ ADC_CHANNEL_10_EN, GPIOA, GPIO_PIN_4 },
|
||
{ ADC_CHANNEL_11_EN, GPIOA, GPIO_PIN_2 },
|
||
{ ADC_CHANNEL_12_EN, GPIOC, GPIO_PIN_2 },
|
||
{ ADC_CHANNEL_13_EN, GPIOC, GPIO_PIN_0 },
|
||
{ ADC_CHANNEL_VBAT_EN, GPIOA, GPIO_PIN_1 },
|
||
{ ADC_CHANNEL_EXT2_EN, GPIOB, GPIO_PIN_1 },
|
||
{ ADC_CHANNEL_EXT3_EN, GPIOB, GPIO_PIN_2 },
|
||
{ 0xffffffff, 0 }, //结束标志
|
||
};
|
||
/*
|
||
NOTE : This function should be modified by the user.
|
||
*/
|
||
|
||
/* For Example */
|
||
GPIO_InitTypeDef GPIO_Handle;
|
||
|
||
//Set gpio to analog.
|
||
for(i = 0; ADC_Pin_Map[i][0] != 0xffffffff; i++)
|
||
{
|
||
if(hadc->Init.ChannelEn & ADC_Pin_Map[i][0])
|
||
{
|
||
GPIO_Handle.Pin = ADC_Pin_Map[i][2];
|
||
GPIO_Handle.Mode = GPIO_MODE_ANALOG;
|
||
GPIO_Handle.Pull = GPIO_NOPULL;
|
||
HAL_GPIO_Init(ADC_Pin_Map[i][1], &GPIO_Handle);
|
||
}
|
||
}
|
||
|
||
/* Enable ADC Clock */
|
||
System_Module_Enable(EN_ADC);
|
||
|
||
/* Clear Pending Interrupt */
|
||
NVIC_ClearPendingIRQ(ADC_IRQn);
|
||
|
||
/* Enable External Interrupt */
|
||
NVIC_EnableIRQ(ADC_IRQn);
|
||
}
|
||
|
||
/************************************************************************
|
||
* function : HAL_ADC_MspDeInit
|
||
* Description:
|
||
* input : hadc : pointer to a ADC_HandleTypeDef structure that contains
|
||
* the configuration information for ADC module
|
||
* return : none
|
||
************************************************************************/
|
||
__weak void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc)
|
||
{
|
||
/*
|
||
NOTE : This function should be modified by the user.
|
||
*/
|
||
|
||
/* For Example */
|
||
if(hadc->Init.DMAMode)
|
||
{
|
||
HAL_DMA_DeInit(hadc->DMA_Handle);
|
||
|
||
hadc->DMA_Handle = NULL;
|
||
}
|
||
|
||
/* Disable ADC Clock */
|
||
System_Module_Disable(EN_ADC);
|
||
|
||
/* Clear Pending Interrupt */
|
||
NVIC_ClearPendingIRQ(ADC_IRQn);
|
||
|
||
/* Disable External Interrupt */
|
||
NVIC_DisableIRQ(ADC_IRQn);
|
||
}
|
||
|
||
/************************************************************************
|
||
* function : HAL_ADC_Init
|
||
* Description: Init the ADC module
|
||
* input : hadc : pointer to a ADC_HandleTypeDef structure that contains
|
||
* the configuration information for ADC module
|
||
* return : HAL_StatusTypeDef
|
||
************************************************************************/
|
||
HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc)
|
||
{
|
||
/* Check the ADC handle allocation */
|
||
if (hadc == NULL)
|
||
{
|
||
return HAL_ERROR;
|
||
}
|
||
|
||
/* Check the parameters */
|
||
if(!IS_ADC_ALL_INSTANCE(hadc->Instance)) return HAL_ERROR;
|
||
if(!IS_ADC_ALL_CONCONVMODE(hadc->Init.ConConvMode)) return HAL_ERROR;
|
||
if(!IS_ADC_ALL_JCHANNELMODE(hadc->Init.JChannelMode)) return HAL_ERROR;
|
||
if(!IS_ADC_ALL_DIFFMODE(hadc->Init.DiffMode)) return HAL_ERROR;
|
||
if(!IS_ADC_ALL_DMAMODE(hadc->Init.DMAMode)) return HAL_ERROR;
|
||
if(!IS_ADC_ALL_OVERMODE(hadc->Init.OverMode)) return HAL_ERROR;
|
||
if(!IS_ADC_ALL_OVERSAMPMODE(hadc->Init.OverSampMode)) return HAL_ERROR;
|
||
if(!IS_ADC_ALL_OVSR(hadc->Init.Oversampling.Ratio)) return HAL_ERROR;
|
||
if(!IS_ADC_ALL_OVSS(hadc->Init.Oversampling.RightBitShift)) return HAL_ERROR;
|
||
if(!IS_ADC_ALL_ANALOGWDGEN(hadc->Init.AnalogWDGEn)) return HAL_ERROR;
|
||
if(!IS_ADC_ALL_CLOCKDIV(hadc->Init.ClockDiv)) return HAL_ERROR;
|
||
if(!IS_ADC_ALL_CHANNELEN(hadc->Init.ChannelEn)) return HAL_ERROR;
|
||
if(!IS_ADC_ALL_TRIG(hadc->Init.ExTrigMode.ExTrigSel)) return HAL_ERROR;
|
||
if(!IS_ADC_ALL_CHANNELEN(hadc->Init.ExTrigMode.JExTrigSel)) return HAL_ERROR;
|
||
|
||
/* Init the low level hardware : GPIO, CLOCK, NVIC, DMA */
|
||
HAL_ADC_MspInit(hadc);
|
||
|
||
//Reset AFE.
|
||
SET_BIT(hadc->Instance->CR2,ADC_CR2_AFE_RSTN);
|
||
//Set Clock DIV.
|
||
MODIFY_REG(hadc->Instance->CR2,ADC_CR2_DIV_MASK,hadc->Init.ClockDiv<<ADC_CR2_DIV_POS);
|
||
|
||
//Set continued convert mode
|
||
if(hadc->Init.ConConvMode)
|
||
SET_BIT(hadc->Instance->CR1,ADC_CR1_CONT);
|
||
else
|
||
CLEAR_BIT(hadc->Instance->CR1,ADC_CR1_CONT);
|
||
|
||
//Overflow
|
||
if(hadc->Init.OverMode == ADC_OVERMODE_ENABLE)
|
||
SET_BIT(hadc->Instance->CR2,ADC_CR2_OVRMOD);
|
||
else
|
||
CLEAR_BIT(hadc->Instance->CR2,ADC_CR2_OVRMOD);
|
||
|
||
//Over Sample Set
|
||
if(hadc->Init.OverSampMode)
|
||
{
|
||
if(hadc->Init.JChannelMode)
|
||
{
|
||
SET_BIT(hadc->Instance->CR2,ADC_CR2_JOVSE); // Inject channel over sample en.
|
||
if(hadc->Init.Oversampling.TriggeredMode)
|
||
SET_BIT(hadc->Instance->CR2,ADC_CR2_JTOVS); // N times sample every trig.
|
||
else
|
||
CLEAR_BIT(hadc->Instance->CR2,ADC_CR2_JTOVS); // 1 time sample every trig.
|
||
}
|
||
|
||
MODIFY_REG(hadc->Instance->CR2,ADC_CR2_OVSR_MASK,hadc->Init.Oversampling.Ratio<<ADC_CR2_OVSR_POS); //over sample rate
|
||
MODIFY_REG(hadc->Instance->CR2,ADC_CR2_OVSS_MASK,hadc->Init.Oversampling.RightBitShift<<ADC_CR2_OVSS_POS); //over sample right shift.
|
||
SET_BIT(hadc->Instance->CR2,ADC_CR2_OVSE); // Regular channel over sample en.
|
||
}
|
||
|
||
//ExTrigSel set
|
||
MODIFY_REG(hadc->Instance->CR1,ADC_CR1_EXTSEL_MASK,hadc->Init.ExTrigMode.ExTrigSel<<ADC_CR1_EXTSEL_POS);
|
||
if(hadc->Init.JChannelMode)
|
||
{
|
||
/* Enable the inject channel */
|
||
SET_BIT(hadc->Instance->CR1, ADC_CR1_JEN);
|
||
//JExTrigSel set
|
||
MODIFY_REG(hadc->Instance->CR1,ADC_CR1_JEXTSEL_MASK,hadc->Init.ExTrigMode.JExTrigSel<<ADC_CR1_JEXTSEL_POS);
|
||
}
|
||
|
||
//Clear the sequence length.
|
||
CLEAR_BIT(hadc->Instance->SQR1,ADC_SQR1_L); //Clear the sequence length.
|
||
|
||
return HAL_OK;
|
||
}
|
||
|
||
/************************************************************************
|
||
* function : HAL_ADC_DeInit
|
||
* Description: DeInit the ADC module
|
||
* input : hadc : pointer to a ADC_HandleTypeDef structure that contains
|
||
* the configuration information for ADC module
|
||
* return : HAL_StatusTypeDef
|
||
************************************************************************/
|
||
HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef* hadc)
|
||
{
|
||
/* Check the ADC handle allocation */
|
||
if (hadc == NULL)
|
||
{
|
||
return HAL_ERROR;
|
||
}
|
||
|
||
HAL_ADC_MspDeInit(hadc);
|
||
|
||
hadc->ChannelNum = 0;
|
||
hadc->ConvCpltCallback = NULL;
|
||
hadc->InjectedConvCpltCallback = NULL;
|
||
hadc->LevelOutOfWindowCallback = NULL;
|
||
memset(&hadc->Init, 0, sizeof(hadc->Init));
|
||
|
||
return HAL_OK;
|
||
}
|
||
|
||
/************************************************************************
|
||
* function : HAL_ADC_ConfigChannel
|
||
* Description: Config the regular channel
|
||
* input : hadc : pointer to a ADC_HandleTypeDef structure that contains
|
||
* the configuration information for ADC module
|
||
* sConfig : pointer to a ADC_ChannelConfTypeDef structure that contains
|
||
* the configuration information for ADC channel
|
||
* return : HAL_StatusTypeDef
|
||
************************************************************************/
|
||
HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConfTypeDef* sConfig)
|
||
{
|
||
if(!IS_ADC_ALL_INSTANCE(hadc->Instance)) return HAL_ERROR;
|
||
if(!IS_ADC_ALL_CHANNEL(sConfig->Channel)) return HAL_ERROR;
|
||
if(!IS_ADC_ALL_SMPCLOCK(sConfig->Smp)) return HAL_ERROR;
|
||
if(!IS_ADC_ALL_SEQUENCE(sConfig->Sq)) return HAL_ERROR;
|
||
|
||
/* Differential mode set*/
|
||
if(hadc->Init.DiffMode)
|
||
{
|
||
if(sConfig->Channel < 8)
|
||
{
|
||
SET_BIT(hadc->Instance->DIFF,1<<sConfig->Channel);
|
||
SET_BIT(hadc->Instance->SIGN,1<<sConfig->Channel); //If define differential mode ,set as sign resault
|
||
}
|
||
else
|
||
return HAL_ERROR;
|
||
}
|
||
else if(sConfig->Channel < 8)
|
||
{
|
||
CLEAR_BIT(hadc->Instance->DIFF,1<<sConfig->Channel);
|
||
CLEAR_BIT(hadc->Instance->SIGN,1<<sConfig->Channel); //If define differential mode ,set as unsign resault
|
||
}
|
||
|
||
if((sConfig->Channel >= 8) && (hadc->Instance->DIFF & (1<<(sConfig->Channel-8)))) return HAL_ERROR;
|
||
|
||
if(sConfig->RjMode == 0)
|
||
{
|
||
if((sConfig->Sq >= 1)&&(sConfig->Sq <= 5))
|
||
MODIFY_REG(hadc->Instance->SQR1,(ADC_CH_MASK << (5*sConfig->Sq )),(sConfig->Channel << (5*sConfig->Sq )));
|
||
else if((sConfig->Sq >= 6)&&(sConfig->Sq <= 11))
|
||
MODIFY_REG(hadc->Instance->SQR2,(ADC_CH_MASK << (5*(sConfig->Sq-6))),(sConfig->Channel << (5*(sConfig->Sq-6))));
|
||
else if((sConfig->Sq >= 12)&&(sConfig->Sq <= 16))
|
||
MODIFY_REG(hadc->Instance->SQR3,(ADC_CH_MASK << (5*(sConfig->Sq-12))),(sConfig->Channel << (5*(sConfig->Sq-12))));
|
||
else
|
||
return HAL_ERROR;
|
||
}
|
||
else
|
||
{
|
||
/* Inject channel */
|
||
MODIFY_REG(hadc->Instance->JSQR,ADC_CH_MASK,sConfig->Channel);
|
||
}
|
||
|
||
MODIFY_REG(hadc->Instance->SQR1,ADC_SQR1_L,(ADC_Handle.ChannelNum-1));
|
||
|
||
/* Set the SMPR to every register*/
|
||
if(sConfig->Channel <= ADC_CHANNEL_7)
|
||
MODIFY_REG(hadc->Instance->SMPR1,(ADC_SMPR_CH_MASK << (4*sConfig->Channel )),(sConfig->Smp << (4*sConfig->Channel )));
|
||
else if((sConfig->Channel >= ADC_CHANNEL_8)&&(sConfig->Channel <= ADC_CHANNEL_15))
|
||
MODIFY_REG(hadc->Instance->SMPR2,(ADC_SMPR_CH_MASK << (4*(sConfig->Channel-8))),(sConfig->Smp << (4*(sConfig->Channel-8))));
|
||
else if((sConfig->Channel >= ADC_CHANNEL_TEMP)&&(sConfig->Channel <= ADC_CHANNEL_EXT3))
|
||
MODIFY_REG(hadc->Instance->SMPR3,(ADC_SMPR_CH_MASK << (4*(sConfig->Channel-16))),(sConfig->Smp << (4*(sConfig->Channel-16))));
|
||
else
|
||
return HAL_ERROR;
|
||
|
||
if(hadc->Init.ChannelEn & ADC_CHANNEL_TEMP_EN)
|
||
{
|
||
SET_BIT(hadc->Instance->TSREF,ADC_TSREF_EN_TS);//Enable the temperature sensor
|
||
System_Delay(1000);
|
||
}
|
||
|
||
if(hadc->Init.ChannelEn & (ADC_CHANNEL_VBGR_EN | ADC_CHANNEL_EXT2_EN | ADC_CHANNEL_EXT3_EN))
|
||
{
|
||
SET_BIT(hadc->Instance->CR2,ADC_CR2_EN_BUF);//Enable the buffer
|
||
System_Delay(1000);
|
||
}
|
||
|
||
return HAL_OK;
|
||
}
|
||
|
||
/************************************************************************
|
||
* function : HAL_ADC_AnalogWDGConfig
|
||
* Description: Config the analog watchdog
|
||
* input : hadc : pointer to a ADC_HandleTypeDef structure that contains
|
||
* the configuration information for ADC module
|
||
* AnalogWDGConfig : pointer to a ADC_AnalogWDGConfTypeDef structure that contains
|
||
* the configuration information for ADC analog watchdog
|
||
* return : HAL_StatusTypeDef
|
||
************************************************************************/
|
||
HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef* hadc, ADC_AnalogWDGConfTypeDef* AnalogWDGConfig)
|
||
{
|
||
if(!IS_ADC_ALL_INSTANCE(hadc->Instance)) return HAL_ERROR;
|
||
if(!IS_ADC_ALL_CHANNEL(AnalogWDGConfig->Channel)) return HAL_ERROR;
|
||
|
||
if (hadc->Init.AnalogWDGEn)
|
||
{
|
||
switch(AnalogWDGConfig->WatchdogMode)
|
||
{
|
||
/* AWDSGL:0; AWDEN:1; JAWDEN:0 */
|
||
case ADC_ANALOGWATCHDOG_RCH_ALL:
|
||
CLEAR_BIT(hadc->Instance->CR1,ADC_CR1_AWDSGL);
|
||
SET_BIT(hadc->Instance->CR1,ADC_CR1_AWDEN);
|
||
CLEAR_BIT(hadc->Instance->CR1,ADC_CR1_JAWDEN);
|
||
break;
|
||
/* AWDSGL:0; AWDEN:0; JAWDEN:1 */
|
||
case ADC_ANALOGWATCHDOG_JCH_ALL:
|
||
CLEAR_BIT(hadc->Instance->CR1,ADC_CR1_AWDSGL);
|
||
CLEAR_BIT(hadc->Instance->CR1,ADC_CR1_AWDEN);
|
||
SET_BIT(hadc->Instance->CR1,ADC_CR1_JAWDEN);
|
||
break;
|
||
/* AWDSGL:0; AWDEN:1; JAWDEN:1 */
|
||
case ADC_ANALOGWATCHDOG_RCH_AND_JCH_ALL:
|
||
CLEAR_BIT(hadc->Instance->CR1,ADC_CR1_AWDSGL);
|
||
SET_BIT(hadc->Instance->CR1,ADC_CR1_AWDEN);
|
||
SET_BIT(hadc->Instance->CR1,ADC_CR1_JAWDEN);
|
||
break;
|
||
/* AWDSGL:1; AWDEN:1; JAWDEN:0 */
|
||
case ADC_ANALOGWATCHDOG_RCH_SINGLE:
|
||
SET_BIT(hadc->Instance->CR1,ADC_CR1_AWDSGL);
|
||
SET_BIT(hadc->Instance->CR1,ADC_CR1_AWDEN);
|
||
CLEAR_BIT(hadc->Instance->CR1,ADC_CR1_JAWDEN);
|
||
MODIFY_REG(hadc->Instance->CR1,ADC_CH_MASK,AnalogWDGConfig->Channel); //The regular watchdog channel set
|
||
break;
|
||
/* AWDSGL:1; AWDEN:0; JAWDEN:1 */
|
||
case ADC_ANALOGWATCHDOG_JCH_SINGLE:
|
||
SET_BIT(hadc->Instance->CR1,ADC_CR1_AWDSGL);
|
||
CLEAR_BIT(hadc->Instance->CR1,ADC_CR1_AWDEN);
|
||
SET_BIT(hadc->Instance->CR1,ADC_CR1_JAWDEN);
|
||
MODIFY_REG(hadc->Instance->CR1,(ADC_CH_MASK<<27),AnalogWDGConfig->Channel<<27); //The inject watchdog channel set
|
||
break;
|
||
/* AWDSGL:1; AWDEN:1; JAWDEN:1 */
|
||
case ADC_ANALOGWATCHDOG_RCH_OR_JCH_SINGLE:
|
||
SET_BIT(hadc->Instance->CR1,ADC_CR1_AWDSGL);
|
||
SET_BIT(hadc->Instance->CR1,ADC_CR1_AWDEN);
|
||
SET_BIT(hadc->Instance->CR1,ADC_CR1_JAWDEN);
|
||
MODIFY_REG(hadc->Instance->CR1,ADC_CH_MASK,AnalogWDGConfig->Channel); //The regular watchdog channel set
|
||
MODIFY_REG(hadc->Instance->CR1,(ADC_CH_MASK<<27),AnalogWDGConfig->Channel<<27); //The inject watchdog channel set
|
||
break;
|
||
|
||
/* AWDSGL:x; AWDEN:0; JAWDEN:0 */
|
||
default: /* ADC_ANALOGWATCHDOG_NONE */
|
||
CLEAR_BIT(hadc->Instance->CR1,ADC_CR1_AWDEN);
|
||
CLEAR_BIT(hadc->Instance->CR1,ADC_CR1_JAWDEN);
|
||
break;
|
||
}
|
||
|
||
/* Configure ADC analog watchdog interrupt */
|
||
if(AnalogWDGConfig->ITMode)
|
||
__HAL_ADC_ENABLE_IT(hadc,ADC_IE_AWDIE);
|
||
else
|
||
__HAL_ADC_DISABLE_IT(hadc,ADC_IE_AWDIE);
|
||
}
|
||
|
||
if(hadc->Init.DiffMode)
|
||
{
|
||
hadc->Instance->HTR = AnalogWDGConfig->HighThreshold<<16;
|
||
hadc->Instance->LTR = AnalogWDGConfig->LowThreshold<<16;
|
||
}
|
||
else
|
||
{
|
||
hadc->Instance->HTR = AnalogWDGConfig->HighThreshold;
|
||
hadc->Instance->LTR = AnalogWDGConfig->LowThreshold;
|
||
}
|
||
/* Return function status */
|
||
return HAL_OK;
|
||
}
|
||
|
||
/************************************************************************
|
||
* function : HAL_ADC_Start
|
||
* Description: Enable and start the ADC convertion
|
||
* input : hadc : pointer to a ADC_HandleTypeDef structure that contains
|
||
* the configuration information for ADC module
|
||
* return : HAL_StatusTypeDef
|
||
************************************************************************/
|
||
HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc)
|
||
{
|
||
/* Check the parameters */
|
||
if(!IS_ADC_ALL_INSTANCE(hadc->Instance)) return HAL_ERROR;
|
||
|
||
/* check the total number of the enabled channels */
|
||
if((READ_BIT(hadc->Instance->SQR1,ADC_SQR1_L)+1) != hadc->ChannelNum) return HAL_ERROR;
|
||
|
||
/* Enable the ADC */
|
||
__HAL_ADC_ENABLE(hadc);
|
||
|
||
/* Clear the SR register */
|
||
__HAL_ADC_CLEAR_FLAG(hadc,ADC_SR_AWD | ADC_SR_OVERF | ADC_SR_EOG | ADC_SR_JEOC | ADC_SR_EOC | ADC_SR_ADRDY);
|
||
|
||
/* Wait ADC ready */
|
||
while(!(hadc->Instance->SR & ADC_SR_ADRDY));
|
||
|
||
if(__HAL_ADC_CHECK_TRIG_REGULAR(hadc, ADC_SOFTWARE_START))
|
||
{
|
||
/* Start covertion */
|
||
SET_BIT(hadc->Instance->CR1,ADC_CR1_SWSTART);
|
||
}
|
||
|
||
/* Return function status */
|
||
return HAL_OK;
|
||
}
|
||
|
||
/************************************************************************
|
||
* function : HAL_ADC_Stop
|
||
* Description: Stop ADC conversion of regular group (and injected channels in
|
||
* case of auto_injection mode), disable ADC peripheral.
|
||
* input : hadc : pointer to a ADC_HandleTypeDef structure that contains
|
||
* the configuration information for ADC module
|
||
* return : HAL_StatusTypeDef
|
||
************************************************************************/
|
||
HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc)
|
||
{
|
||
/* Check the parameters */
|
||
if(!IS_ADC_ALL_INSTANCE(hadc->Instance)) return HAL_ERROR;
|
||
|
||
if(hadc->Init.ConConvMode)
|
||
{
|
||
/* Set stop flag */
|
||
SET_BIT(hadc->Instance->CR2, ADC_CR2_ADC_STP);
|
||
/* Waitting stop flag be cleared */
|
||
while(READ_BIT(hadc->Instance->CR2, ADC_CR2_ADC_STP));
|
||
}
|
||
|
||
/* Disable the ADC peripheral */
|
||
__HAL_ADC_DISABLE(hadc);
|
||
|
||
/* Clear the SR register */
|
||
__HAL_ADC_CLEAR_FLAG(hadc,ADC_SR_AWD | ADC_SR_OVERF | ADC_SR_EOG | ADC_SR_JEOC | ADC_SR_EOC | ADC_SR_ADRDY);
|
||
|
||
/* Return function status */
|
||
return HAL_OK;
|
||
}
|
||
|
||
/************************************************************************
|
||
* function : HAL_ADC_Start_IT
|
||
* Description: Enable ADC, start conversion of regular group with interruption.
|
||
* input : hadc : pointer to a ADC_HandleTypeDef structure that contains
|
||
* the configuration information for ADC module
|
||
* return : HAL_StatusTypeDef
|
||
************************************************************************/
|
||
HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc)
|
||
{
|
||
/* Check the parameters */
|
||
if(!IS_ADC_ALL_INSTANCE(hadc->Instance)) return HAL_ERROR;
|
||
|
||
/* Enable the ADC */
|
||
__HAL_ADC_ENABLE(hadc);
|
||
|
||
/* Clear the SR register */
|
||
__HAL_ADC_CLEAR_FLAG(hadc,ADC_SR_AWD | ADC_SR_OVERF | ADC_SR_EOG | ADC_SR_JEOC | ADC_SR_EOC | ADC_SR_ADRDY);
|
||
|
||
/* Disable all interruptions before enabling the desired ones */
|
||
__HAL_ADC_DISABLE_IT(hadc, ADC_IE_EOCIE | ADC_IE_EOGIE | ADC_IE_OVERFIE | ADC_IE_JEOCIE);
|
||
|
||
__HAL_ADC_ENABLE_IT(hadc, ADC_IE_EOCIE | ADC_IE_EOGIE);
|
||
|
||
|
||
/* Enable ADC overrun interrupt */
|
||
/* If hadc->Init.OverMode is set to ADC_OVERMODE_DISABLE, only then is
|
||
ADC_IE_OVERFIE enabled; otherwise data overwrite is considered as normal
|
||
behavior and no CPU time is lost for a non-processed interruption */
|
||
if (hadc->Init.OverMode == ADC_OVERMODE_DISABLE)
|
||
{
|
||
__HAL_ADC_ENABLE_IT(hadc, ADC_IE_OVERFIE);
|
||
}
|
||
|
||
if(__HAL_ADC_CHECK_TRIG_REGULAR(hadc, ADC_SOFTWARE_START))
|
||
{
|
||
/* Start covertion */
|
||
SET_BIT(hadc->Instance->CR1,ADC_CR1_SWSTART);
|
||
}
|
||
|
||
/* Return function status */
|
||
return HAL_OK;
|
||
}
|
||
|
||
/************************************************************************
|
||
* function : HAL_ADC_Stop_IT
|
||
* Description: Stop ADC conversion of regular group (and injected group in
|
||
* case of auto_injection mode), disable interrution of
|
||
* end-of-conversion, disable ADC peripheral.
|
||
* input : hadc : pointer to a ADC_HandleTypeDef structure that contains
|
||
* the configuration information for ADC module
|
||
* return : HAL_StatusTypeDef
|
||
************************************************************************/
|
||
HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc)
|
||
{
|
||
/* Check the parameters */
|
||
if(!IS_ADC_ALL_INSTANCE(hadc->Instance)) return HAL_ERROR;
|
||
|
||
if(hadc->Init.ConConvMode)
|
||
{
|
||
/* Set stop flag */
|
||
SET_BIT(hadc->Instance->CR2, ADC_CR2_ADC_STP);
|
||
/* Waitting stop flag be cleared */
|
||
while(READ_BIT(hadc->Instance->CR2, ADC_CR2_ADC_STP));
|
||
}
|
||
|
||
/* Disable the ADC peripheral */
|
||
__HAL_ADC_DISABLE(hadc);
|
||
|
||
/* Disable all interruptions before enabling the desired ones */
|
||
__HAL_ADC_DISABLE_IT(hadc, ADC_IE_EOCIE | ADC_IE_EOGIE | ADC_IE_OVERFIE | ADC_IE_JEOCIE);
|
||
|
||
/* Clear the SR register */
|
||
__HAL_ADC_CLEAR_FLAG(hadc,ADC_SR_AWD | ADC_SR_OVERF | ADC_SR_EOG | ADC_SR_JEOC | ADC_SR_EOC | ADC_SR_ADRDY);
|
||
|
||
/* Return function status */
|
||
return HAL_OK;
|
||
}
|
||
|
||
/************************************************************************
|
||
* function : HAL_ADC_Start_DMA
|
||
* Description: Enable ADC, start conversion of regular group and transfer result through DMA.
|
||
* input : hadc : pointer to a ADC_HandleTypeDef structure that contains
|
||
* the configuration information for ADC module
|
||
* : pData : Destination Buffer address.
|
||
* : Length : Number of data to be transferred from ADC peripheral to memory.
|
||
* return : HAL_StatusTypeDef
|
||
************************************************************************/
|
||
HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length)
|
||
{
|
||
HAL_StatusTypeDef tmp_hal_status;
|
||
|
||
/* Check the parameters */
|
||
if(!IS_ADC_ALL_INSTANCE(hadc->Instance)) return HAL_ERROR;
|
||
|
||
/* Specific case for first call occurrence of this function (DMA transfer */
|
||
/* not activated and ADC disabled), DMA transfer must be activated */
|
||
/* with ADC disabled. */
|
||
if (READ_BIT(hadc->Instance->CR1,ADC_CR1_DMA) == 0UL)
|
||
{
|
||
if(READ_BIT(hadc->Instance->CR2, ADC_CR2_ADC_EN))
|
||
{
|
||
/* Disable ADC */
|
||
__HAL_ADC_DISABLE(hadc);
|
||
}
|
||
|
||
/* Enable ADC DMA mode */
|
||
SET_BIT(hadc->Instance->CR1,ADC_CR1_DMA);
|
||
}
|
||
|
||
/* Enable the ADC peripheral */
|
||
__HAL_ADC_ENABLE(hadc);
|
||
|
||
/* Clear the SR register */
|
||
__HAL_ADC_CLEAR_FLAG(hadc,ADC_SR_AWD | ADC_SR_OVERF | ADC_SR_EOG | ADC_SR_JEOC | ADC_SR_EOC | ADC_SR_ADRDY);
|
||
|
||
/* Disable all interruptions before enabling the desired ones */
|
||
__HAL_ADC_DISABLE_IT(hadc, ADC_IE_EOCIE | ADC_IE_EOGIE | ADC_IE_OVERFIE | ADC_IE_JEOCIE);
|
||
|
||
/* Start the DMA channel */
|
||
tmp_hal_status = HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, Length);
|
||
|
||
/* Enable conversion of regular group. */
|
||
/* If software start has been selected, conversion starts immediately. */
|
||
/* If external trigger has been selected, conversion will start at next */
|
||
/* trigger event. */
|
||
|
||
/* Start ADC group regular conversion */
|
||
if(__HAL_ADC_CHECK_TRIG_REGULAR(hadc, ADC_SOFTWARE_START))
|
||
{
|
||
/* Start covertion */
|
||
SET_BIT(hadc->Instance->CR1,ADC_CR1_SWSTART);
|
||
}
|
||
|
||
/* Return function status */
|
||
return tmp_hal_status;
|
||
}
|
||
|
||
/************************************************************************
|
||
* function : HAL_ADC_Stop_DMA
|
||
* Description: Stop ADC conversion of regular group (and injected group in
|
||
* case of auto_injection mode), disable ADC DMA transfer, disable
|
||
* ADC peripheral.
|
||
* input : hadc : pointer to a ADC_HandleTypeDef structure that contains
|
||
* the configuration information for ADC module
|
||
* return : HAL_StatusTypeDef
|
||
************************************************************************/
|
||
HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc)
|
||
{
|
||
/* Check the parameters */
|
||
if(!IS_ADC_ALL_INSTANCE(hadc->Instance)) return HAL_ERROR;
|
||
|
||
if(hadc->Init.ConConvMode)
|
||
{
|
||
/* Set stop flag */
|
||
SET_BIT(hadc->Instance->CR2, ADC_CR2_ADC_STP);
|
||
/* Waitting stop flag be cleared */
|
||
while(READ_BIT(hadc->Instance->CR2, ADC_CR2_ADC_STP));
|
||
}
|
||
|
||
/* Waitting stop flag be cleared */
|
||
while(READ_BIT(hadc->Instance->CR2, ADC_CR2_ADC_STP));
|
||
|
||
/* Disable the DMA channel (in case of DMA in circular mode or stop */
|
||
/* while DMA transfer is on going) */
|
||
HAL_DMA_Abort(hadc->DMA_Handle);
|
||
|
||
/* Disable ADC overrun interrupt */
|
||
__HAL_ADC_DISABLE_IT(hadc, ADC_IE_OVERFIE);
|
||
|
||
/* 2. Disable the ADC peripheral */
|
||
/* Update "tmp_hal_status" only if DMA channel disabling passed, to keep */
|
||
/* in memory a potential failing status. */
|
||
|
||
/* Disable the ADC peripheral */
|
||
__HAL_ADC_DISABLE(hadc);
|
||
|
||
/* Disable all interruptions before enabling the desired ones */
|
||
__HAL_ADC_DISABLE_IT(hadc, ADC_IE_EOCIE | ADC_IE_EOGIE | ADC_IE_OVERFIE | ADC_IE_JEOCIE);
|
||
|
||
/* Clear the SR register */
|
||
__HAL_ADC_CLEAR_FLAG(hadc,ADC_SR_AWD | ADC_SR_OVERF | ADC_SR_EOG | ADC_SR_JEOC | ADC_SR_EOC | ADC_SR_ADRDY);
|
||
|
||
/* Disable ADC DMA (ADC DMA configuration of continuous requests is kept) */
|
||
CLEAR_BIT(hadc->Instance->CR1,ADC_CR1_DMA);
|
||
|
||
/* Return function status */
|
||
return HAL_OK;
|
||
}
|
||
|
||
/************************************************************************
|
||
* function : HAL_ADC_GetValue
|
||
* Description: ADC retrieve conversion value intended to be used with polling or interruption
|
||
* input : hadc : pointer to a ADC_HandleTypeDef structure that contains
|
||
* the configuration information for ADC module
|
||
* return : uint32_t the ADC covert result.
|
||
************************************************************************/
|
||
uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef *hadc)
|
||
{
|
||
/* Check the parameters */
|
||
if(!IS_ADC_ALL_INSTANCE(hadc->Instance)) return HAL_ERROR;
|
||
|
||
return (hadc->Instance->DR);
|
||
}
|
||
|
||
/************************************************************************
|
||
* function : HAL_ADC_PollForEvent
|
||
* Description: Poll for ADC event.
|
||
* input : hadc : pointer to a ADC_HandleTypeDef structure that contains
|
||
* the configuration information for ADC module
|
||
* : EventType: the ADC event type. can be :ADC_SR_AWD,ADC_SR_OVERF,ADC_SR_EOG,ADC_SR_JEOC,ADC_SR_EOC
|
||
* : Timeout : Polling timeout.
|
||
* return : HAL_StatusTypeDef
|
||
************************************************************************/
|
||
HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef *hadc, uint32_t EventType, uint32_t Timeout)
|
||
{
|
||
__IO uint32_t uiTimeout;
|
||
|
||
/* Check the parameters */
|
||
if(!IS_ADC_ALL_INSTANCE(hadc->Instance)) return HAL_ERROR;
|
||
if(!IS_ADC_EVENT_TYPE(EventType)) return HAL_ERROR;
|
||
|
||
uiTimeout = Timeout;
|
||
/* Check selected event flag */
|
||
while (__HAL_ADC_GET_FLAG(hadc, EventType) == 0UL)
|
||
{
|
||
/* Check if timeout is disabled (set to infinite wait) */
|
||
if(uiTimeout)
|
||
{
|
||
uiTimeout--;
|
||
if(uiTimeout == 0)
|
||
return HAL_TIMEOUT;
|
||
}
|
||
}
|
||
|
||
if(EventType == ADC_SR_OVERF)
|
||
{
|
||
__HAL_ADC_CLEAR_FLAG(hadc, ADC_SR_OVERF);
|
||
if (hadc->Init.OverMode == ADC_OVERMODE_ENABLE)
|
||
{
|
||
/* Clear ADC Overrun flag only if Overrun is set to ADC_OVERMODE_ENABLE(Over written) */
|
||
return HAL_ERROR;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
__HAL_ADC_CLEAR_FLAG(hadc, EventType);
|
||
}
|
||
|
||
/* Return function status */
|
||
return HAL_OK;
|
||
}
|
||
|
||
/************************************************************************
|
||
* function : HAL_ADC_InjectedStart_IT
|
||
* Description: Enable ADC, start conversion of injected channel with interruption.
|
||
* input : hadc : pointer to a ADC_HandleTypeDef structure that contains
|
||
* the configuration information for ADC module
|
||
* return : HAL_StatusTypeDef
|
||
************************************************************************/
|
||
HAL_StatusTypeDef HAL_ADC_InjectedStart_IT(ADC_HandleTypeDef* hadc)
|
||
{
|
||
/* Check the parameters */
|
||
if(!IS_ADC_ALL_INSTANCE(hadc->Instance)) return HAL_ERROR;
|
||
|
||
/* Clear the SR register */
|
||
__HAL_ADC_CLEAR_FLAG(hadc, ADC_SR_JEOC);
|
||
|
||
__HAL_ADC_ENABLE_IT(hadc, ADC_IE_JEOCIE);
|
||
|
||
/* Enable ADC overrun interrupt */
|
||
/* If hadc->Init.OverMode is set to ADC_OVERMODE_DISABLE, only then is
|
||
ADC_IE_OVERFIE enabled; otherwise data overwrite is considered as normal
|
||
behavior and no CPU time is lost for a non-processed interruption */
|
||
if (hadc->Init.OverMode == ADC_OVERMODE_DISABLE)
|
||
{
|
||
__HAL_ADC_ENABLE_IT(hadc, ADC_IE_OVERFIE);
|
||
}
|
||
|
||
if(__HAL_ADC_CHECK_TRIG_INJECTED(hadc, ADC_SOFTWARE_START))
|
||
{
|
||
/* Start covertion */
|
||
SET_BIT(hadc->Instance->CR1,ADC_CR1_JSWSTART);
|
||
}
|
||
|
||
/* Return function status */
|
||
return HAL_OK;
|
||
}
|
||
|
||
/************************************************************************
|
||
* function : HAL_ADC_InjectedStop_IT
|
||
* Description: Stop ADC conversion of injected channel, disable interrution of
|
||
* end-of-conversion, disable ADC peripheral.
|
||
* input : hadc : pointer to a ADC_HandleTypeDef structure that contains
|
||
* the configuration information for ADC module
|
||
* return : HAL_StatusTypeDef
|
||
************************************************************************/
|
||
HAL_StatusTypeDef HAL_ADC_InjectedStop_IT(ADC_HandleTypeDef* hadc)
|
||
{
|
||
/* Return function status */
|
||
return (HAL_ADC_Stop_IT(hadc));
|
||
}
|
||
|
||
/************************************************************************
|
||
* function : HAL_ADC_InjectedGetValue
|
||
* Description: ADC retrieve injected channel conversion value intended to be used with polling or interruption
|
||
* input : hadc : pointer to a ADC_HandleTypeDef structure that contains
|
||
* the configuration information for ADC module
|
||
* return : uint32_t the ADC covert result.
|
||
************************************************************************/
|
||
uint32_t HAL_ADC_InjectedGetValue(ADC_HandleTypeDef *hadc)
|
||
{
|
||
/* Check the parameters */
|
||
if(!IS_ADC_ALL_INSTANCE(hadc->Instance)) return HAL_ERROR;
|
||
|
||
return (hadc->Instance->JDR);
|
||
}
|
||
|
||
/************************************************************************
|
||
* function : HAL_ADC_Polling
|
||
* Description: Polling to get the results of the ADC converter.
|
||
* input : hadc : pointer to a ADC_HandleTypeDef structure that contains
|
||
* the configuration information for ADC module
|
||
* : pData : Destination Buffer address.
|
||
* : Length : Number of data to be transferred from ADC peripheral to memory.
|
||
* : Timeout : Polling timeout.
|
||
* return : HAL_StatusTypeDef
|
||
************************************************************************/
|
||
HAL_StatusTypeDef HAL_ADC_Polling(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length, uint32_t Timeout)
|
||
{
|
||
uint32_t tmp_hal_status;
|
||
__IO uint32_t uiTimeout;
|
||
|
||
if(HAL_ADC_Start(hadc) != HAL_OK) return HAL_ERROR;
|
||
if(!pData) return HAL_ERROR;
|
||
|
||
hadc->AdcResults = pData;
|
||
uiTimeout = Timeout;
|
||
|
||
while(Length)
|
||
{
|
||
tmp_hal_status = hadc->Instance->SR;
|
||
if(tmp_hal_status & ADC_SR_EOC)
|
||
{
|
||
*hadc->AdcResults = hadc->Instance->DR | HAL_ADC_EOC_FLAG;
|
||
__HAL_ADC_CLEAR_FLAG(hadc, ADC_SR_EOC);
|
||
|
||
hadc->AdcResults++;
|
||
Length--;
|
||
}
|
||
if(tmp_hal_status & ADC_SR_JEOC)
|
||
{
|
||
*hadc->AdcResults = hadc->Instance->JDR | HAL_ADC_JEOC_FLAG;
|
||
__HAL_ADC_CLEAR_FLAG(hadc, ADC_SR_JEOC);
|
||
hadc->AdcResults++;
|
||
Length--;
|
||
}
|
||
if(tmp_hal_status & ADC_SR_OVERF)
|
||
{
|
||
__HAL_ADC_CLEAR_FLAG(hadc, ADC_SR_OVERF);
|
||
}
|
||
if(tmp_hal_status & ADC_SR_EOG)
|
||
{
|
||
__HAL_ADC_CLEAR_FLAG(hadc, ADC_SR_EOG);
|
||
break;
|
||
}
|
||
|
||
if(uiTimeout)
|
||
{
|
||
uiTimeout--;
|
||
if(uiTimeout == 0)
|
||
return HAL_TIMEOUT;
|
||
}
|
||
}
|
||
|
||
HAL_ADC_Stop(hadc);
|
||
|
||
return HAL_OK;
|
||
}
|