/**
 * @file Drv_AFE_ADC.c
 * @author 吳星萍 (iris@e-besthealth.com)
 * @brief ADC 調用接口
 * @version 0.1
 * @date 2020-06-17
 *
 * @copyright BEST HEALTH ELECTRONIC INC (c) 2019
 *
 * Compiler Ver. : V3.57
 * IDE3000  Ver. : V8.03
 * MCU/CFG  Ver. : BH67F5362/1.1
 */
#include "Project_Global.h"
#include "BH67F5362.h"
#include "Drv_AFE_ADC.h"
#include "Drv_GPIO.h"

/**
 * @brief 開啟ADC通道，并獲取ADC值
 *
 * @param channel ADC采樣通道
 * @return unsigned int
 */
unsigned int Drv_GetADC(unsigned char channel)
{
	SET_ADC_DATA_0_11();
	SET_ADC_POWER(ON);
	SET_ADC_REF_AVDD();
	SET_ADC_CLOCK_SYS_32();
	switch (channel)
	{
	case ADC_CHANNEL_AN0:	  SET_ADC_CHANNEL_AN0(); SET_PC0_AN0();	break;
	case ADC_CHANNEL_AN1:	  SET_ADC_CHANNEL_AN1(); SET_PC1_AN1();	break;
	case ADC_CHANNEL_AN2:	  SET_ADC_CHANNEL_AN2(); SET_PC2_AN2();	break;
	case ADC_CHANNEL_AN3:	  SET_ADC_CHANNEL_AN3(); SET_PC3_AN3();	break;
	case ADC_CHANNEL_AN4:	  SET_ADC_CHANNEL_AN4(); SET_PC4_AN4();	break;
	case ADC_CHANNEL_AN5:	  SET_ADC_CHANNEL_AN5(); SET_PC5_AN5();	break;
	case ADC_CHANNEL_AN6:	  SET_ADC_CHANNEL_AN6(); SET_PC6_AN6();	break;
	case ADC_CHANNEL_AN7:	  SET_ADC_CHANNEL_AN7(); SET_PC7_AN7();	break;
	case ADC_CHANNEL_AN8:	  SET_ADC_CHANNEL_AN8(); SET_PD0_AN8();	break;
	case ADC_CHANNEL_AN9:	  SET_ADC_CHANNEL_AN9(); SET_PD1_AN9();	break;
	case ADC_CHANNEL_AN12:	  SET_ADC_CHANNEL_AN12(); SET_PA1_AN12();	break;
	case ADC_CHANNEL_AN13:	  SET_ADC_CHANNEL_AN13(); SET_PA3_AN13();	break;
	case ADC_CHANNEL_AN14:	  SET_ADC_CHANNEL_AN14(); SET_PA4_AN14();	break;
	case ADC_CHANNEL_AN15:	  SET_ADC_CHANNEL_AN15(); SET_PA5_AN15();	break;
	case ADC_CHANNEL_AVDD:	  SET_ADC_CHANNEL_AVDD();	break;
	case ADC_CHANNEL_AVDD_2:  SET_ADC_CHANNEL_AVDD_2();	break;
	case ADC_CHANNEL_AVDD_4:  SET_ADC_CHANNEL_AVDD_4();	break;
	case ADC_CHANNEL_VR:	  SET_ADC_CHANNEL_VR();	    break;
	case ADC_CHANNEL_VR_2:	  SET_ADC_CHANNEL_VR_2();	break;
	case ADC_CHANNEL_VR_4:	  SET_ADC_CHANNEL_VR_4();	break;
	case ADC_CHANNEL_AVSS:	  SET_ADC_CHANNEL_AVSS();	break;
	default:	break;
	}
	SET_ADC_STARTCONVERT();
	while (_adbz);
	unsigned int temp;
	temp = _sadol;
	temp += _sadoh*256;
	SET_ADC_POWER(OFF);
	return temp;
}

/**
 * @brief 開啟ADC通道，連續獲取N筆ADC，去除最大最小后取平均值
 *
 * @param channel ADC采樣通道
 * @return unsigned int
 */
unsigned int Drv_GetADC_AVGn(unsigned char channel, unsigned char Cnt)
{
	SET_ADC_DATA_0_11();
	SET_ADC_POWER(ON);
	SET_ADC_REF_AVDD();
	SET_ADC_CLOCK_SYS_32();
	switch (channel)
	{
	case ADC_CHANNEL_AN0:	  SET_ADC_CHANNEL_AN0(); SET_PC0_AN0();	break;
	case ADC_CHANNEL_AN1:	  SET_ADC_CHANNEL_AN1(); SET_PC1_AN1();	break;
	case ADC_CHANNEL_AN2:	  SET_ADC_CHANNEL_AN2(); SET_PC2_AN2();	break;
	case ADC_CHANNEL_AN3:	  SET_ADC_CHANNEL_AN3(); SET_PC3_AN3();	break;
	case ADC_CHANNEL_AN4:	  SET_ADC_CHANNEL_AN4(); SET_PC4_AN4();	break;
	case ADC_CHANNEL_AN5:	  SET_ADC_CHANNEL_AN5(); SET_PC5_AN5();	break;
	case ADC_CHANNEL_AN6:	  SET_ADC_CHANNEL_AN6(); SET_PC6_AN6();	break;
	case ADC_CHANNEL_AN7:	  SET_ADC_CHANNEL_AN7(); SET_PC7_AN7();	break;
	case ADC_CHANNEL_AN8:	  SET_ADC_CHANNEL_AN8(); SET_PD0_AN8();	break;
	case ADC_CHANNEL_AN9:	  SET_ADC_CHANNEL_AN9(); SET_PD1_AN9();	break;
	case ADC_CHANNEL_AN12:	  SET_ADC_CHANNEL_AN12(); SET_PA1_AN12();	break;
	case ADC_CHANNEL_AN13:	  SET_ADC_CHANNEL_AN13(); SET_PA3_AN13();	break;
	case ADC_CHANNEL_AN14:	  SET_ADC_CHANNEL_AN14(); SET_PA4_AN14();	break;
	case ADC_CHANNEL_AN15:	  SET_ADC_CHANNEL_AN15(); SET_PA5_AN15();	break;
	case ADC_CHANNEL_AVDD:	  SET_ADC_CHANNEL_AVDD();	break;
	case ADC_CHANNEL_AVDD_2:  SET_ADC_CHANNEL_AVDD_2();	break;
	case ADC_CHANNEL_AVDD_4:  SET_ADC_CHANNEL_AVDD_4();	break;
	case ADC_CHANNEL_VR:	  SET_ADC_CHANNEL_VR();	    break;
	case ADC_CHANNEL_VR_2:	  SET_ADC_CHANNEL_VR_2();	break;
	case ADC_CHANNEL_VR_4:	  SET_ADC_CHANNEL_VR_4();	break;
	case ADC_CHANNEL_AVSS:	  SET_ADC_CHANNEL_AVSS();	break;
	default:	break;
	}

	unsigned char i;
	volatile unsigned int AdcData;
	unsigned long AdcData_Sum = 0;
	unsigned int ADCData_Max = 0x00;
	unsigned int ADCData_Min = 0xffff;

	for ( i = 0; i < Cnt; i++)
	{
		SET_ADC_STARTCONVERT();
		while (_adbz);
		AdcData = _sadol;
		AdcData += _sadoh*256;
		AdcData_Sum += AdcData;
		if (AdcData > ADCData_Max)
		{
			ADCData_Max = AdcData;
		}
		if (AdcData < ADCData_Min)
		{
			ADCData_Min = AdcData;
		}
	}
	AdcData = (AdcData_Sum - ADCData_Max - ADCData_Min) / (Cnt - 2);
	SET_ADC_POWER(OFF);
	return AdcData;
}
