/** ##########################################################################
**     Filename  :
**     Project   :
**     Module    :
**     Processor :
**     Version   :
**     Compiler  :
**     Date/Time :
**     Abstract  :
**     Contents  :
**     Note      :
**
**     (c) Copyright dmdz Co.,Ltd
**  --------------------------------------------------------------------------
**               R E V I S I O N   H I S T O R Y
**  --------------------------------------------------------------------------
**  Date       Ver   Author             Description

**  -20191106-  --V01--  --LYJ---  --初版--
**  -20230602-  --V1.0--  --mingyea---  --修改--

** #########################################################################*/

/*---------------------------------------------------------------------------
- I N C L U D E   F I L E S
----------------------------------------------------------------------------*/
#include "queue_entity.h"
#include "logic_timer.h"
#include "adc.h"
#include "gpio.h"
#include "common_memory.h"
#include "dma.h"


/*---------------------------------------------------------------------------
- D E F I N E S / M A C R O S
----------------------------------------------------------------------------*/


/*---------------------------------------------------------------------------
- T Y P E   D E F I N I T I O N S
----------------------------------------------------------------------------*/


/*---------------------------------------------------------------------------
- S T A T I C   V A R I A B L E S
----------------------------------------------------------------------------*/


/*---------------------------------------------------------------------------
* G L O B A L   V A R I A B L E S
----------------------------------------------------------------------------*/
adc_s g_adc;


/*---------------------------------------------------------------------------
- C O N S T A N T S
----------------------------------------------------------------------------*/


/*---------------------------------------------------------------------------
- F U N C T I O N   P R O T O T Y P E
----------------------------------------------------------------------------*/
static void adc_data_operate(void);


/*---------------------------------------------------------------------------
|Prototype			:
|Called by			:
|Preconditions		:
|Input parameters	:
|Output parameters	:
|Return value		:
|Description		:ADC中断服务函数
----------------------------------------------------------------------------*/
void ADC_IRQHandler(void)
{
	u8 i;
	u32 l_adc_org;
	#ifdef ADC_DEBUG_EN
	g_adc.test[0]++;
	#endif
	if((FL_ENABLE == FL_ADC_IsEnabledIT_EndOfConversion(ADC))
		&& (FL_SET == FL_ADC_IsActiveFlag_EndOfConversion(ADC)))
	{
		#ifdef ADC_DEBUG_EN
		g_adc.test[1]++;
		#endif
		i=g_adc.channel_id;

		if(i<ADC_LOGIC_CHANNEL_MAX)
		{
			//将原始值读取
			l_adc_org = FL_ADC_ReadConversionData(ADC);
			g_adc.channel[i].init_value = l_adc_org;

		}

		g_adc.channel_id++;
		if(g_adc.channel_id>=ADC_LOGIC_CHANNEL_MAX)
		{
			g_adc.channel_id=0u;
			#ifdef ADC_DEBUG_EN
			g_adc.test[2]++;
			#endif
		}

		#if 0
		if(ADCChannelCount == 0)
		{
			/* 获取外部通道采样值 */
			GetVSample =  FL_ADC_ReadConversionData(ADC);
			ADCChannelCount++;
		}
		else
		{
			/* 获取VREF1P2采样值 */
			Get122VSample =  FL_ADC_ReadConversionData(ADC);
			ADCChannelCount = 0;
			ADCComplete = 1U;
		}
		#endif
	}
	FL_ADC_ClearFlag_EndOfConversion(ADC);
}


/*---------------------------------------------------------------------------
|Prototype			:
|Called by			:
|Preconditions		:
|Input parameters	:
|Output parameters	:
|Return value		:
|Description		:ADC初始化
----------------------------------------------------------------------------*/
void AdcInit(void)
{
	/* ADC 时钟设置 */
	FL_ADC_CommonInit((FL_ADC_CommonInitTypeDef*)&g_ADC_CommonInitStruct);
	FL_ADC_Init(ADC, (FL_ADC_InitTypeDef*)&g_ADC_InitStruct);

	#ifdef ADC_ENABLE_DMA_MODE
	FL_ADC_EnableDMAReq(ADC);
	#else
	/* 使能通道转换完成中断 */
	FL_ADC_EnableIT_EndOfConversion(ADC);
	/* NVIC中断配置 */
	NVIC_ClearPendingIRQ(ADC_IRQn);
	NVIC_DisableIRQ(ADC_IRQn);
	NVIC_SetPriority(ADC_IRQn, NVIC_PRIORITY_ADC);
	NVIC_EnableIRQ(ADC_IRQn);
	#endif
}

/*---------------------------------------------------------------------------
|Prototype			:
|Called by			:
|Preconditions		:
|Input parameters	:  channel_id 见宏 ADC_LOGIC_CHN_BAT 等
|Output parameters	:
|Return value		:
|Description		:
----------------------------------------------------------------------------*/
void adc_init()
{
	u8  i;

	AdcInit();
	dma_init();

	common_memory_clear((u8*)&g_adc,sizeof(g_adc));
	#if 0
	/* 使能通道ADC_IN1 */
	FL_ADC_EnableSequencerChannel(ADC, ADC_CHANNEL_1_PHY_ID);
	FL_ADC_EnableSequencerChannel(ADC, ADC_CHANNEL_0_PHY_ID);
	/* 使能通道ADC_VREF1P2 */
	FL_ADC_EnableSequencerChannel(ADC, FL_ADC_INTERNAL_VREF1P2);
	#else
	//倒序
	for(i = 0u; i < ADC_LOGIC_CHANNEL_MAX; i++)
	{
		FL_ADC_EnableSequencerChannel(ADC, g_adc_drv_channel[i]);
	}
	#endif
	/* 使能VREF BUFFER */
	/* 为了考虑功耗BUFFER可关闭，从使能到ADC可以正常采样需要100us的建立时间，本例程配置慢速通道较长的采样时间，来保证建立时间满足。 */
	FL_VREF_EnableVREFBuffer(VREF);
	FL_ADC_ClearFlag_EndOfConversion(ADC);                      /* 清标志 */
	/* 启动ADC */
	FL_ADC_Enable(ADC);
	/* 开始转换 */
	FL_ADC_EnableSWConversion(ADC);
}


/*---------------------------------------------------------------------------
|Prototype			:
|Called by			:
|Preconditions		:
|Input parameters	:
|Output parameters	:
|Return value		:
|Description		:
----------------------------------------------------------------------------*/
void adc_de_init(void)
{
	FL_ADC_DeInit(ADC);
	//FL_ADC_Disable(ADC);
	FL_DMA_DeInit(DMA);
}


/*---------------------------------------------------------------------------
|Prototype			:
|Called by			:
|Preconditions		:
|Input parameters	:
|Output parameters	:
|Return value		:
|Description		: 任務
----------------------------------------------------------------------------*/
void adc_task(void)
{
	adc_data_operate();
	adc_manage_task();
}



/*---------------------------------------------------------------------------
|Prototype			:
|Called by			:
|Preconditions		:
|Input parameters	:
|Output parameters	:
|Return value		:
|Description		:
----------------------------------------------------------------------------*/
static void adc_data_operate(void)
{
	u8 i;
	#ifdef ADC0_CHANNEL_FILETER_EN
	u8 k;
	u16 l_refh;
	u8 l_count=0u;
	u8 l_total=0u;
	u16 l_sum=0u;
	#endif

	#ifdef ADC_ENABLE_DMA_MODE
	if(FL_DMA_IsActiveFlag_TransferComplete(DMA, FL_DMA_CHANNEL_ADC))
	{
		#ifdef ADC_DEBUG_EN
		g_adc.test[3]++;
		#endif
		FL_DMA_ClearFlag_TransferComplete(DMA, FL_DMA_CHANNEL_ADC);

		#if ADC_ENABLE_DMA_MODE == 0u
		FL_ADC_ClearFlag_EndOfConversion(ADC);                      /* 清标志 */
		FL_ADC_Disable(ADC);                                         /* 关闭ADC */
		for(i = 0u; i < ADC_LOGIC_CHANNEL_MAX; i++)
		{
			FL_ADC_DisableSequencerChannel(ADC, g_adc_drv_channel[i]);
		}
		#endif

		i=ADC_LOGIC_CHANNEL_VREF1P2;
		g_adc.channel[i].result_value =  ( (u32)( (u32)(g_adc.init_value[i] *1000u) / ADC_RESOLUTION_MASK) * (u32)ADC_VREFH)/1000u;
		for(i = ADC_LOGIC_CHANNEL_USE_START; i <= ADC_LOGIC_CHANNEL_END; i++)
		{
			#if 0
			g_adc.channel[i].result_value =  ( (u32)( (u32)(g_adc.init_value[i] *1000u) / ADC_RESOLUTION_MASK) * (u32)ADC_VREFH)/1000u;
			#else  //ADC_VREF1P2
			g_adc.channel[i].result_value = ((uint64_t)g_adc.init_value[i] * 3000ul * (ADC_VREF)) / ((uint32_t)g_adc.init_value[ADC_LOGIC_CHANNEL_VREF1P2] * 4095);
			#endif
		}

		//如果是单次模式
		#if ADC_ENABLE_DMA_MODE == 0u

			g_adc.timecount =0u;
			g_adc.state =0u;

			dma_init();

			for(i = 0u; i < ADC_LOGIC_CHANNEL_MAX; i++)
			{
				FL_ADC_EnableSequencerChannel(ADC, g_adc_drv_channel[i]);
			}

			/* 使能VREF BUFFER */
			/* 为了考虑功耗BUFFER可关闭，从使能到ADC可以正常采样需要100us的建立时间，本例程配置慢速通道较长的采样时间，来保证建立时间满足。 */
			FL_VREF_EnableVREFBuffer(VREF);
			FL_ADC_ClearFlag_EndOfConversion(ADC);                      /* 清标志 */
			/* 启动ADC */
			FL_ADC_Enable(ADC);
			/* 开始转换 */
			FL_ADC_EnableSWConversion(ADC);

		#endif
	}
	#else

	i=ADC_LOGIC_CHANNEL_VREF1P2;
	g_adc.channel[i].result_value =  ( (u32)( (u32)(g_adc.channel[i].init_value *1000u) / ADC_RESOLUTION_MASK) * (u32)ADC_VREFH)/1000u;
	for(i = ADC_LOGIC_CHANNEL_USE_START; i <= ADC_LOGIC_CHANNEL_END; i++)
	{
		#if 0
		g_adc.channel[i].result_value =  ( (u32)( (u32)(g_adc.channel[i].init_value *1000u) / ADC_RESOLUTION_MASK) * (u32)ADC_VREFH)/1000u;
		#else  //ADC_VREF1P2
		g_adc.channel[i].result_value =  ( (u32)( (u32)(g_adc.channel[i].init_value *ADC_VREF1P2) / g_adc.channel[ADC_LOGIC_CHANNEL_VREF1P2].init_value) );
		#endif
	}

	#endif

	//濾波計算
	#ifdef ADC0_CHANNEL_FILETER_EN
	for(i = 0u; i < ADC_LOGIC_CHANNEL_MAX; i++)
	{
		l_count = g_adc.channel[i].filter_count;
		if(g_adc.channel[i].filter_over == 0u)
		{
			l_total = l_count+1u;
		}
		else
		{
			l_total = ADC0_CHANNEL_FILTER_TIME;
		}
		g_adc.channel[i].filter_buf[l_count] = g_adc.channel[i].result_value;
		l_sum=0u;
		for(k=0u;k<l_total;k++)
		{
			l_sum += g_adc.channel[i].filter_buf[k];
		}
		g_adc.channel[i].result_filter_value = l_sum/l_total;
		//
		g_adc.channel[i].filter_count++;
		if(g_adc.channel[i].filter_count>=ADC0_CHANNEL_FILTER_TIME)
		{
			g_adc.channel[i].filter_count=0u;
			g_adc.channel[i].filter_over=1u;
		}
	}
	#endif


	#if ADC_ENABLE_DMA_MODE == 0u

		g_adc.timecount++;
		if(g_adc.timecount>=ADC_TASK_TIMEOUT)
		{
			#ifdef ADC_DEBUG_EN
			g_adc.test[4]++;
			#endif
			g_adc.timecount=0u;
			adc_init();
		}
		g_adc.state =0u;

	#endif
}


/*---------------------------------------------------------------------------
|Prototype			:
|Called by			:
|Preconditions		:
|Input parameters	:  channel_id 见宏 ADC_LOGIC_CHN_BAT 等
|Output parameters	:
|Return value		:
|Description		: 读取最终的值
----------------------------------------------------------------------------*/
adc_voltage_t adc_get_voltage_value(u8 channel_id)
{
	adc_voltage_t l_result =0;
	if(channel_id<ADC_LOGIC_CHANNEL_MAX)
	{
		#ifdef ADC0_CHANNEL_FILETER_EN
		l_result = g_adc.channel[channel_id].result_filter_value;
		#else
		l_result = g_adc.channel[channel_id].result_value;
		#endif
	}
	return l_result;
}



/*end line*/

