/*Includes ----------------------------------------------*/
#include "tool.h"
#include "nrf_delay.h"
#include "bsp_adc.h"
#include "bsp_time.h"
#include "exception.h"
#include "system.h"
#include "fml_adc.h"

/*Private macro ------------------------------------------------------------------------------------------------------------------------------------*/


/*STRUCTION ------------------------------------------------------------------------------------------------------------------------------------*/
typedef struct _fml_adc
{
	int16_t																			adc_value[CHANNEL_MAX];																																	//所有通道的adc采样值		

	uint32_t																		sample_point;																																						//采样点

	uint32_t																		switch_sample_point;																																		//转换采样点
	
	uint32_t																		trigger_base_point;																																			//触发基点
	
	fml_adc_sample_update_notify_callback				m_notify_cb;																																						//采样更新通知回调
	
} Fml_Adc_t;



/*Local Variable ------------------------------------------------------------------------------------------------------------------------------------*/
static Fml_Adc_t ob_fml_adc;

/*Local Functions ------------------------------------------------------------------------------------------------------------------------------------*/
static void fml_adc_samplecallback(int16_t *newset_adc_value)
{
	Fml_Adc_All_Channel_Adc_Value_t cur_all_adc_value;

	cur_all_adc_value.channel_0_adc_value =	ob_fml_adc.adc_value[0]	=	newset_adc_value[0];
	cur_all_adc_value.channel_1_adc_value = ob_fml_adc.adc_value[1]	=	newset_adc_value[1];
	cur_all_adc_value.channel_2_adc_value = ob_fml_adc.adc_value[2]	=	newset_adc_value[2];
	cur_all_adc_value.channel_3_adc_value = ob_fml_adc.adc_value[3]	=	newset_adc_value[3];
	cur_all_adc_value.channel_4_adc_value = ob_fml_adc.adc_value[4]	=	newset_adc_value[4];
	cur_all_adc_value.channel_5_adc_value = ob_fml_adc.adc_value[5]	=	newset_adc_value[5];
	cur_all_adc_value.channel_6_adc_value = ob_fml_adc.adc_value[6]	=	newset_adc_value[6];
	cur_all_adc_value.channel_7_adc_value = ob_fml_adc.adc_value[7]	=	newset_adc_value[7];
	
	if(ob_fml_adc.m_notify_cb != NULL)
	{
		ob_fml_adc.m_notify_cb(ob_fml_adc.sample_point,cur_all_adc_value);
	}
	
}
static void fml_adc_timecallback(void* t)
{
	uint32_t cur_time = NRF_RTC0->COUNTER;
	
	if(cur_time<ob_fml_adc.trigger_base_point) cur_time += 16777216;
	
	if((cur_time - ob_fml_adc.trigger_base_point)/32.768 >= ob_fml_adc.switch_sample_point)
	{
		//更新触发基点
		ob_fml_adc.trigger_base_point = NRF_RTC0->COUNTER;
		//更新采样点
		ob_fml_adc.sample_point = ob_fml_adc.switch_sample_point;
		//触发采样
		ADC_Sample(fml_adc_samplecallback);
		//设置下次触发采样时间点
		ob_fml_adc.switch_sample_point = (ob_fml_adc.switch_sample_point == FML_ADC_SAMPLE_POINT_1)?FML_ADC_SAMPLE_POINT_2:FML_ADC_SAMPLE_POINT_1;
	}
}
static void cb_adcWakeup(uint32_t t)
{
	ADC_Enable();
	
	//更新触发基点
	ob_fml_adc.trigger_base_point = NRF_RTC0->COUNTER;
	//唤醒采样一次
	ob_fml_adc.sample_point = FML_ADC_SAMPLE_POINT_0;
	ADC_Sample(fml_adc_samplecallback);
	//设置下次触发采样时间点
	ob_fml_adc.switch_sample_point = FML_ADC_SAMPLE_POINT_1;
	//注册定时器1毫秒回调函数
	TIME_Regist(fml_adc_timecallback);
}

static void cb_adcSleep(uint32_t t)
{
	ADC_Disable();
	TIME_UnRegist(fml_adc_timecallback);
}
/*API ------------------------------------------------------------------------------------------------------------------------------------*/
/**
	@brief 		初始化adc功能模块
	@param 		无
	@return 	错误代码					- [out]	-1失败，0成功
*/
int	fml_adc_Init(void)
{
	//重置结构体
	memset(&ob_fml_adc,0,sizeof(ob_fml_adc));

	ADC_SetPinChannel(PIN_ADC_CHARGMEASURE, PIN_ADC_CHARGMEASURE_CHANNEL,NRF_GPIO_PIN_NOPULL);
	ADC_SetPinChannel(PIN_ADC_BAT_IN, PIN_ADC_BAT_CHANNEL,NRF_GPIO_PIN_NOPULL);
	ADC_SetPinChannel(PIN_CHARGING, PIN_CHARGING_CHANNEL,NRF_GPIO_PIN_NOPULL);
	Wakeup_Regist(cb_adcWakeup);
	Sleep_Regist(cb_adcSleep);
	
	return 0;
}

/**
	@brief 		adc采样更新通知回调注册
	@param 		cb								-	[in]	回调函数注册
	@return 	错误代码					- [out]	-1失败，0成功
*/
int	fml_adc_sample_update_notify_register(fml_adc_sample_update_notify_callback cb)
{
	if(cb != NULL)
	{
		ob_fml_adc.m_notify_cb = cb;
		
		return 0;
	}
	
	return -1;
}

/**
	@brief 		adc读值
	@param 		channel						-	[in]	需要读取的通道
	@param 		value							-	[out]	返回通道的值
	@return 	错误代码					- [out]	-1失败，0成功
*/
int	fml_adc_get_value(uint32_t channel,int16_t *value)
{
	if(channel >= CHANNEL_MAX)
	{
		return -1;
	}
	else
	{
		*value = ob_fml_adc.adc_value[channel];
	}
	return 0;
}

/**
	@brief 		设置ADC通道
	@param 		pin								-	[in]	需要设置的引脚
	@param 		channel						-	[in]	需要设置的通道
	@param 		pin_pull					-	[in]	需要设置的通道上下拉
	@return 	错误代码					- [out]	-1失败，0成功
*/
int	fml_adc_set_pin_channel(uint32_t pin, uint32_t channel, nrf_gpio_pin_pull_t pin_pull)
{
	uint32_t err;
	
	err = ADC_SetPinChannel(pin, channel, pin_pull);
	
	if(err != ADC_OP_SUCCESS)return -1;
	
	return 0;
}

/**
	@brief 		移除ADC通道
	@param 		pin								-	[in]	需要移除的引脚
	@param 		channel						-	[in]	需要移除的通道
	@return 	错误代码					- [out]	-1失败，0成功
*/
int	fml_adc_remove_pin_channel(uint32_t pin, uint32_t channel)
{
	uint32_t err;
	
	err = ADC_RemovePinChannel(pin, channel);
	
	if(err != ADC_OP_SUCCESS)return -1;
	
	return 0;
}





















