#include "driver/JQDriver.h"
#include "base/delay.h"
#include "hardware/adc_cfg.h"
#include "base/utility.h"
#include "hardware/power.h"
#include "JQChecker.h"
#include "CheckerExt.h"

/*
@brief 统计模块的上电充能，具有电压设置功能,采集档位 R10_0p1mA_1p6mA_UC
@param0 总线电压
@param1 超时时间 0.1ms
@param2 充电结束时的AD值
@rtv1   返回总线电流低于设置AD值的时间
*/
void JQ_Test_PowerOn(void)
{
	uint8_t uc_rtv = 0;
	uint16_t us_rsult[2];
	uint16_t us_max;
	uint16_t us_shake;
	JQBUS_OFF;
	uc_rtv = PowerCalibration_set(checker_runcfg.params[0],checker_runcfg.params[0]-1);

	Power_SetSampleRange_Seep(Checker_PowerOn_Sample_R,ADC_SPEED_HIGH);
	//POWER_ON
	delay_os_ms(100);
	JQBUS_ON;
	delay_us(20);
	us_rsult[1] =   AD_GetChgEnergy(checker_runcfg.params[1],checker_runcfg.params[2], &us_max,&us_shake);
	delay_os_ms(100);
	us_rsult[0] = Power_GetBousV();
	Checker_SetRtv(us_rsult,checker_runcfg.rtv_count);
	Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
	
	
	
}
/*
@brief 设置总线电压
@param1 总线电压
@rtv1   总线电压
*/
void JQ_Test_SetBusV(void)
{
	uint8_t uc_rtv = 0;
	uint16_t us_h_v,us_m_v;
	us_h_v = checker_runcfg.params[0];
	if(us_h_v < 55)
	{
		uc_rtv = 1;

	}else{
		us_m_v  = 50;
		uc_rtv |= PowerCalibration_set(us_h_v,us_m_v);
		JQBUS_ON;
		delay_ms(100);
		us_h_v = Power_GetBousV();
		Checker_SetRtv(&us_h_v,checker_runcfg.rtv_count);
	}
	Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
	
}
/*
@brief 测量总线基本电压
@rtv1 返回总线电流 单位0.1uA
*/
void JQ_Test_BaseCur(void)
{
	uint16_t ul_cur[2];
	JQBUS_W_1
	delay_ms(250);
	ul_cur[0] = ADC_GetBaseStableCur();
	JQBUS_W_0
	delay_ms(100);
	ul_cur[1] = ADC_GetBaseStableCur();
	JQBUS_W_1
	delay_ms(20);
	Checker_MaskResult(0,checker_runcfg.task_info.runindex);
	Checker_SetRtv(ul_cur,checker_runcfg.rtv_count);
}
/*
@brief 扫描总线上的电子模块 1发
@param0 使能或失能通信反码信息采集
@param1 1 uid数据全0验证  其他不验证
@rtv1 最大反馈电流
@rtv2 最大反馈时间
@rtv3 最小反馈电流
@rtv4 最小反馈时间
@rtv5 UID 2Bytes
@rtv6 UID 2Bytes
@rtv7 UID 2Bytes
@rtv8 UID 2Bytes
*/
void JQ_Test_ScanUID(void)
{
	uint16_t  aus_temp[8];
	uint8_t uc_rtv = 0;
	uint8_t uc_ack;
	uint8_t uc_count = 0;
	uint32_t ul_temp;
	for(uc_count = 0; uc_count < 4; uc_count++)
	{
		aus_temp[uc_count] = 0x00;
	}
	for(uc_count = 4; uc_count < 8; uc_count++)
	{
		aus_temp[uc_count] = 0x55;
	}
	JQ_ScanUIDBegin();
	if(checker_runcfg.params[0] > 0)
	{
		JQ_FreeBack_Prapare(1);
	}
	uc_ack = JQ_ScanReadUID(CHECKER_NET_ID,(uint8_t*)&aus_temp[4]);
//	uc_rtv = JQ_ScanReadUID(checker_runcfg.jq_params[2],(uint8_t*)&aus_temp[4]);

	if(uc_ack < 1)
	{
		uc_rtv = 1;
	}
	
	ul_temp = Power_ConvCur(JQ_FreeBack_MaxCur,JQDriver_Sample_R);   
	ul_temp = (ul_temp + 500)/1000;
	
	aus_temp[0] = ul_temp ;
	aus_temp[1] = (uint16_t)((((589u*1000)*JQ_FreeBack_MaxTime)/JQ_Read_AD_Sample_C+400)/1000) ;
	ul_temp = Power_ConvCur(JQ_FreeBack_MinCur,JQDriver_Sample_R);
	ul_temp = (ul_temp + 500)/1000;
	aus_temp[2] = ul_temp;
	aus_temp[3] =  (uint16_t)((((589u*1000)*JQ_FreeBack_MinTime)/JQ_Read_AD_Sample_C+400)/1000)  ;
	if(checker_runcfg.params[1] == 0)
	{
		for(uc_count = 4; uc_count < 8; uc_count++)
		{
			if(aus_temp[uc_count] != 0x00)
			{
				uc_rtv |= 0x01;
			}
		}
	}
	Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
	Checker_SetRtv(aus_temp,checker_runcfg.rtv_count);	
}
/*
@brief 读取芯片码
@rtv 芯片代码2字节
*/
void JQ_Test_ReadChipID(void)
{
	uint8_t uc_rtv = 0;
	uint16_t us_chipid;
	uint8_t uc_ack;
	uc_ack = JQ_ReadChipID(CHECKER_NET_ID,&us_chipid);
	if(uc_ack < 1)
	{
		uc_rtv = 1;
	}
	Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
	Checker_SetRtv(&us_chipid,checker_runcfg.rtv_count);	
}
/*
@brief 密码验证
@param0 密码原码验证使能
*/
void JQ_Test_PWCheck(void)
{
	uint8_t auc_pwd[4]={0,0,0,0};
	uint8_t uc_count = 0,uc_ack = 0,uc_rtv = 0;
	if(checker_runcfg.params[0] > 0)
	{
		uc_ack = JQ_ReadOTP(CHECKER_NET_ID,11,4,auc_pwd);
		if(uc_ack != 4)
		{
			uc_rtv = 1;
		}
		uc_ack = auc_pwd[3] ;
		auc_pwd[3] = auc_pwd[0];
		auc_pwd[0] = uc_ack;
		uc_ack = auc_pwd[2] ;
		auc_pwd[2] = auc_pwd[1];
		auc_pwd[1] = uc_ack;
	}
	JQ_VerifyPWD(auc_pwd);
	Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
}

/*
@brief OTP全0检测
@param0 UID区和密码区验证标志 1不验证 0 验证
@param1 延时区和保留区验证 1不验证 0验证，错误标记区
@param2 用户存储区
*/

void JQ_Test_OTPCheck(void)
{
	uint8_t uc_optbuf[16];
	uint8_t uc_rtv = 0;
	uint8_t uc_ack;
	uint8_t uc_count = 0;
	//出厂校准
	uc_ack = JQ_ReadOTP(CHECKER_NET_ID,0,1,uc_optbuf);
	if(uc_ack !=1 || uc_optbuf[0] == 0xFF || uc_optbuf[0] == 0)
	{
		uc_rtv = 1;
		Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
		return ;
	}
	if(checker_runcfg.params[0] < 1)
	{
		uc_count = 0;
		while(uc_count < 16)
		{
			uc_optbuf[uc_count++] = 0x55;
		}
		uc_ack = JQ_ReadOTP(CHECKER_NET_ID,3,12,uc_optbuf);
		if(uc_ack != 12)
		{
			uc_rtv = 1;
		}
		uc_count = 0;
		while(uc_count < 12)
		{
			if(uc_optbuf[uc_count++] != 0)
			{
				uc_rtv = 1;
			}
		}
	}
	if(checker_runcfg.params[1] < 1)
	{
		uc_count = 0;
		while(uc_count < 16)
		{
			uc_optbuf[uc_count++] = 0x55;
		}
		//延时区
		uc_ack = JQ_ReadOTP(CHECKER_NET_ID,15,2,uc_optbuf); //2Bytes
		if(uc_ack != 2)
		{
			uc_rtv = 1;
		}
		//保留区 3-16损坏使用
		uc_ack = JQ_ReadOTP(CHECKER_NET_ID,17,3,uc_optbuf+2);//3Bytes
		if(uc_ack != 3)
		{
			uc_rtv = 1;
		}
		//错误标记区
		uc_ack = JQ_ReadOTP(CHECKER_NET_ID,26,6,uc_optbuf+5);//6Bytes
		if(uc_ack != 6)
		{
			uc_rtv = 1;
		}
		
		uc_count = 0;
		//OTP31 30 特殊处理，其高4bit不错比较
		uc_optbuf[10] &= 0x0F;
		uc_optbuf[9] &= 0x0F;
		while(uc_count < 11)
		{
			if(uc_optbuf[uc_count++] != 0)
			{
				uc_rtv = 1;
			}
		}
	}
	
	if(checker_runcfg.params[2] < 1)
	{
		uc_count = 0;
		while(uc_count < 16)
		{
			uc_optbuf[uc_count++] = 0x55;
		}
		uc_ack = JQ_ReadOTP(CHECKER_NET_ID,20,4,uc_optbuf);
		if(uc_ack != 4)
		{
			uc_rtv = 1;
		}
		uc_count = 0;
		while(uc_count < 4)
		{
			if(uc_optbuf[uc_count++] != 0)
			{
				uc_rtv = 1;
			}
		}
	}
	Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
}
/*
@brief 工厂成测标志检测
*/
void JQ_Test_FTCheck(void)
{
	uint16_t us_opt;
	uint8_t uc_rtv = 0;
	uint8_t uc_ack;
	us_opt = 0x00;
	uc_ack = JQ_ReadOTP(CHECKER_NET_ID,24,2,(uint8_t*)&us_opt);
	if(uc_ack != 2)
	{
		uc_rtv = 1;
	}
	if(us_opt != 0xFFFF)
	{
		uc_rtv = 2;
	}
  us_opt=0;
	uc_ack = JQ_ReadOTP(CHECKER_NET_ID,0,1,(uint8_t*)&us_opt);
	if(uc_ack != 1)
	{
		uc_rtv = 3;
	}
  if(us_opt==0)
  {
    uc_rtv=4;
  }

	Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
}

/*
@brief 读芯片状态
@param0 比较掩码，状态与掩码与等于掩码返回正常
*/
void JQ_Test_ReadState(void)
{
	uint8_t state = 0x00;
	uint8_t uc_rtv = 0;
	uint8_t uc_ack;
	uc_ack = JQ_ReadState(CHECKER_NET_ID,&state);
	if((state & checker_runcfg.params[0]) != checker_runcfg.params[0])
	{
		uc_rtv = 1;
	}
	if(uc_ack < 1)
	{
		uc_rtv = 1;
	}
	checker_runcfg.params[0] = state;
	Checker_SetRtv(checker_runcfg.params,checker_runcfg.rtv_count);
	Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
}

/*
@brief 写入OTP数据
@param0 2字节OTP数据
@param1 2字节OTP数据
*/
void JQ_Test_WriteUserInfo(void)
{
	uint8_t uc_rtv = 0;
	uint8_t uc_ack;
	uint8_t uc_count = 0;
	uint8_t uc_wcount ;
	uint32_t ul_temp = 0;
	uint32_t ul_write = checker_runcfg.params[1];
	ul_write <<= 16;
	ul_write |= checker_runcfg.params[0];
	JQ_EnWOTP();
	JQ_EnWOTP();
	
	uc_ack = JQ_ReadOTP(CHECKER_NET_ID,20,4,(uint8_t*)&ul_temp);
	if(uc_ack < 1)
	{
		uc_rtv = 1;
	}
	uc_wcount = 0;
	//要不全部为0，要不除去低5位一致，其他bits为0
	if(ul_temp == 0)
	{
		uc_wcount = 4;
	}
	if((ul_temp & (~0x01Fu)) == 0)
	{
		if((ul_temp & 0x01Fu) == (ul_write & 0x01Fu))
		{
			uc_wcount = 4;
		}
	}
	if(uc_wcount == 0 || uc_rtv == 1)
	{
		uc_rtv = 1;
		Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
		return;
	}
	
	uc_wcount = JQ_WriteOTP(20,4,(uint8_t*)&ul_write);
	if(uc_count != 4)
	{
		uc_rtv = 1;
		Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
		return;
	}
	ul_temp = 0;
	uc_ack = JQ_ReadOTP(CHECKER_NET_ID,20,4,(uint8_t*)&ul_temp);
	if(uc_ack < 1)
	{
		uc_rtv = 1;
	}
	if(ul_temp != ul_write)
	{
		uc_rtv = 1;
	}
	Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
}

/*
@brief 写入OTP数据
@param0 OTP 地址
@param1 写入数据长度
@param2 2Bytes OTP数据
@param3 2Bytes OTP数据
@param4 2Bytes OTP数据
@param5 2Bytes OTP数据
*/
void JQ_Test_WriteOTP(void)
{
	uint8_t uc_rtv = 0;
	uint8_t uc_ack;
	uint8_t uc_count = 0;
	uint8_t uc_wcount ;
	uint8_t uc_otpaddr;
	uint8_t* uc_pbuf;
	uint8_t uc_optbuf[8];
	JQ_EnWOTP();
	JQ_EnWOTP();
	uc_otpaddr = checker_runcfg.params[0];
	uc_count   = checker_runcfg.params[1];
	if(uc_count > 8)
		uc_count = 8;
	uc_pbuf = (uint8_t*)(&checker_runcfg.params[2]);
	uc_wcount = JQ_WriteOTP(uc_otpaddr,uc_count,uc_pbuf);
	if(uc_wcount != uc_count)
	{
		uc_rtv = 1;
		Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
		return;
	}
	uc_ack = JQ_ReadOTP(CHECKER_NET_ID,uc_otpaddr,uc_count,(uint8_t*)uc_optbuf);
	if(uc_ack < 1)
	{
		uc_rtv = 1;
	}
	for(uc_wcount = 0; uc_wcount < uc_count; uc_wcount++)
	{
		if(uc_optbuf[uc_wcount] != uc_pbuf[uc_wcount])
		{
			break;
		}
	}
	if(uc_wcount != uc_count)
	{
		uc_rtv = 1;
	}
	Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
}



/*
@brief 读OTP
@param0 OTP地址
@param1 OTP 数量
*/

void JQ_Test_ReadOTP(void)
{
	uint8_t uc_rtv = 0;
	uint8_t uc_ack;
	uint8_t uc_count = 0;
	uint8_t uc_wcount ;
	uint8_t uc_otpaddr;
	uint16_t uc_optbuf[16];
	uc_otpaddr = checker_runcfg.params[0];
	uc_count   = checker_runcfg.params[1];
	if((uc_otpaddr+uc_count) > 32)
	{
			Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
			return;
	}
	uc_ack = JQ_ReadOTP(CHECKER_NET_ID,uc_otpaddr,uc_count,(uint8_t*)uc_optbuf);
	if(uc_ack < 1)
	{
		uc_rtv = 1;
	}
	Checker_SetRtv(uc_optbuf,checker_runcfg.rtv_count);
	Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
}

/*
@brief 充能统计
@param0 充电超时0.1us
@param1 充电电流判线值,AD值
@param2 充电末电流结束值，单位0.1uA
@param3 充电最长时间,单位100ms
@param4 充电高压保持时间，单位0.1s

@rtv0 充能值 单位0.1ms
@rtv1 充末电流 单位0.1uA
@rtv2 充电最大电流 单位0.1Ma
@rtv3 充电抖动幅值 adv
*/

void JQ_Test_ChgEnergy(void)
{
	uint16_t us_sample_timeout =     checker_runcfg.params[0];
	uint16_t us_adend =     checker_runcfg.params[1];
	uint16_t us_chgend_cur = checker_runcfg.params[2];
	uint16_t us_timeout = checker_runcfg.params[3];
	uint32_t ul_holdtime =  checker_runcfg.params[4];
	
	
	uint16_t us_array[4];
	uint16_t us_energy = 0;
	uint16_t us_end_cur = 2000;
	uint16_t us_max_cur = 0;
	uint16_t us_shake = 65535;
	uint32_t ul_temp;
	uint8_t uc_rtv = 0;

	JQ_Chage(0);	
	Power_SetSampleRange_Seep(JQChecker_ChgEnger_Sample_R,ADC_SPEED_HIGH);
	delay_ms(1);
	us_energy = AD_GetChgEnergy(us_sample_timeout,us_adend,&us_max_cur,&us_shake);
	us_max_cur = (Power_ConvCur(us_max_cur,JQChecker_ChgEnger_Sample_R) /100+5)/10;    
	ADC_CurChnnelSet(AN_MAL_CH, ADC_SPEED_MIDLE);
	ul_temp = AD_CurMonitor(ul_holdtime*1000);
	if(ul_temp > us_shake)
	{
		us_shake = ul_temp;
	}
	us_timeout++;
	while(us_timeout > 0)
	{
		
		us_end_cur = ADC_GetBaseStableCur();
		
		if(us_end_cur < us_chgend_cur)
		{
			break;
		}
		us_timeout--;
	}
//	if(us_end_cur > us_chgend_cur)
//	{
//		uc_rtv = 1;
//	}
	CurrentSampleR_Def;
	Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
	us_array[0] = us_energy;
	us_array[1] = us_end_cur;
	us_array[2] = us_max_cur;
	us_array[3] = us_shake;
	
	Checker_SetRtv(us_array,checker_runcfg.rtv_count);
	
}

/*
@brief DAC检测
@param  DAC检测的起始值
@param  DAC检测的结束值
*/
void JQ_Test_CheckDAC(void)
{
	uint16_t uc_bg_dac = checker_runcfg.params[0];
	uint16_t uc_end_dac = checker_runcfg.params[1];
	uint8_t uc_rtv = 1,uc_state;
	while(uc_bg_dac >= uc_end_dac)
	{
		JQ_ChargJudge(uc_bg_dac);
		uc_state = 0;
		if( JQ_ReadState(CHECKER_NET_ID,&uc_state) < 1)
		{
			uc_bg_dac = 0;
			uc_rtv = 1;
			break;
		}
		if(uc_state & 0x80)
		{
			uc_rtv = 0;
			break;
		}
		if(uc_bg_dac == 0)
		{
			break;
		}
		uc_bg_dac--;
	}
	if(uc_bg_dac < uc_end_dac)
	{
		uc_bg_dac = 0;
	}
	Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
	Checker_SetRtv(&uc_bg_dac,checker_runcfg.rtv_count);
}


/*
@brief 写延时
@param 延时时间
*/
void JQ_Test_SetDelay(void)
{
	uint16_t us_delaytime =  checker_runcfg.params[0];
	JQ_WriteDelay(CHECKER_NET_ID,us_delaytime);
	Checker_MaskResult(0,checker_runcfg.task_info.runindex);
}
/*
@brief 读延时
@param 延时时间
*/
void JQ_Test_ReadDelay(void)
{
	uint8_t uc_rtv = 0;
	uint16_t us_delaytime,us_temp;
	uc_rtv = JQ_ReadDelay(CHECKER_NET_ID,&us_delaytime);
	uc_rtv = uc_rtv < 1?1:0;
	
	us_temp = (us_delaytime >> 8) & 0x0FF;
	us_temp |= (us_delaytime << 8) & 0xFF00;
	Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
	Checker_SetRtv(&us_temp,checker_runcfg.rtv_count);
}

/*
@brief 校准
@param1 校准周期
@param2 脉冲个数
*/
void JQ_Test_ClkTrim(void)
{
	uint16_t us_cycle =  checker_runcfg.params[0];
	uint16_t us_count =  checker_runcfg.params[1];
	JQ_TimeAmend(us_cycle,us_count);
	Checker_MaskResult(0,checker_runcfg.task_info.runindex);
}
/*
@brief 放电，快速放电仅JQ2012才有
@param0 放电功能 0 普通放电 1 快速放电
@param1 快速放电时间
*/

void JQ_Test_Discharge(void)
{
	uint16_t us_time = checker_runcfg.params[1];
	JQ_DisChage();
	if(checker_runcfg.params[0] == 1 &&  us_time > 0)
	{
		JQ_FastDisChage(1);
		delay_os_ms(100*us_time);
		JQ_FastDisChage(0);
	}
	Checker_MaskResult(0,checker_runcfg.task_info.runindex);
}

/*
@brief 复位
*/
void JQ_Test_Reset(void)
{
	uint8_t ack = 0,uc_state;
	uint8_t i = 0;
	for(i = 0; i < 5;i++)
	{
		delay_os_ms(20);
		JQ_Reset();  //软复位
		delay_os_ms(20);
		ack = JQ_ReadState(0,&uc_state);  //读状态
		if(ack == 0)
			continue;
		if((uc_state & 0x7B) == 0x18)
		{
			break;
		}
	}
	delay_os_ms(20);
	JQ_DisChage(); //内部放电
	if(i < 5)
	{
		ack = 0;
	}else{
		ack = 1;
	}
	Checker_MaskResult(ack,checker_runcfg.task_info.runindex);
}

/*
@brief 起爆使能
*/
void JQ_Test_BootEn(void)
{
	JQ_BoomActive();
	Checker_MaskResult(0,checker_runcfg.task_info.runindex);
}
/*
@brief 清除起爆命令
*/
void JQ_Test_ClearBoom()
{
	uint16_t us_temp;
	JQ_CheckerBoomCmd(1,&us_temp);
	
}
/*
@brief 起爆充能
@param0 启动电流 adc
@param1 脉冲个数
@param2 延时采集起爆充能

@rtv1 起爆后充电能量
@rtv2 起爆脉冲波动
@rtv3 起爆后充电电流
@rtv4 起爆后充电电流波动
*/

void JQ_Test_BoomEnergy(void)
{
	uint16_t us_adc_bg = checker_runcfg.params[0];
	uint16_t us_plus_count = checker_runcfg.params[1];
	uint16_t us_delay = checker_runcfg.params[2];
	uint16_t aus_rtv[4];// us_shake,max_cul,us_shake2,us_energy;
	uint32_t ul_max_cur;
	us_plus_count =  JQ_CheckerBoomCmd(us_plus_count,&aus_rtv[1]);
	if(checker_runcfg.params[1] > 652)
	{

		Power_SetSampleRange_Seep(JQChecker_ChgEnger_Sample_R,ADC_SPEED_HIGH);
		delay_ms(us_delay);
		aus_rtv[0] = AD_GetChgEnergy(40000,us_adc_bg,&aus_rtv[2],&aus_rtv[3]);
		ul_max_cur =  Power_ConvCur(aus_rtv[2],JQChecker_ChgEnger_Sample_R);
		ul_max_cur = (ul_max_cur + 500)/1000;//0.01mA
		aus_rtv[2] = ul_max_cur;
		
	}else{
		aus_rtv[0] = aus_rtv[2] = aus_rtv[3] = 0;
	}
	if(us_plus_count != CHECKER_NET_ID)
	{
			Checker_MaskResult(1,checker_runcfg.task_info.runindex);
	}else{
			Checker_MaskResult(0,checker_runcfg.task_info.runindex);
	}
	
	Checker_SetRtv(aus_rtv,checker_runcfg.rtv_count);
	
}

/*
@brief 使能通讯末电流采样
*/
void JQ_Test_EnCommEndCur(void)
{
	JQ_CommEnd_MaxCur = 0;
	JQ_CommEnd_CurEn = 1;
	Checker_MaskResult(0,checker_runcfg.task_info.runindex);
}
/*
@brief 获取通讯末电流采样，关闭电流采样
@rtv   返回上次采集的通讯末电流
*/
void JQ_Test_GetCommEndCur(void)
{
	JQ_CommEnd_CurEn = 0;
	Checker_SetRtv((uint16_t *)&JQ_CommEnd_MaxCur,checker_runcfg.rtv_count);
	Checker_MaskResult(0,checker_runcfg.task_info.runindex);
}
/*
@brief 关总线
*/
void JQ_Test_PowerOff(void)
{
	JQ_Test_Discharge();
	delay_ms(20);
	JQBUS_OFF;
	PowerCalibration_set(POWER_DEF_V,POWER_DEF_V-10);
}
/*
@brief 缓存数据写入OTP数据
@param0 OTP 地址
@param1 缓存区起始
@param2 写入数据长度
*/
void JQ_Test_WriteBuf2OTP(void)
{
	uint8_t uc_rtv = 0;
	uint8_t uc_ack;
	uint8_t uc_count = 0;
	uint8_t uc_wcount ;
	uint8_t uc_otpaddr;
	uint8_t* uc_pbuf;
	uint8_t uc_optbuf[16];
	JQ_EnWOTP();
	JQ_EnWOTP();
	if((checker_runcfg.params[1] + checker_runcfg.params[2] > CHECKER_WRITE_BUF) || (checker_runcfg.params[1] > 16))
	{
		uc_rtv = 1;
		Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
		return;
	}
	if(CheckCRC_8(&Checker_FacBuf[2],Checker_FacBuf[0]) != Checker_FacBuf[1])
	{
		uc_rtv = 1;
		Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
		return;
	}
	memset(uc_optbuf,0x55,16);
	uc_otpaddr = checker_runcfg.params[0];
	uc_count   = checker_runcfg.params[2];
	uc_pbuf = &Checker_FacBuf[2]+checker_runcfg.params[1];
	
	uc_wcount = JQ_WriteOTP(uc_otpaddr,uc_count,uc_pbuf);
	if(uc_wcount != uc_count)
	{
		uc_rtv = 1;
		Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
		return;
	}
	uc_ack = JQ_ReadOTP(CHECKER_NET_ID,uc_otpaddr,uc_count,(uint8_t*)uc_optbuf);
	if(uc_ack < 1)
	{
		uc_rtv = 1;
	}
	for(uc_wcount = 0; uc_wcount < uc_count; uc_wcount++)
	{
		if(uc_optbuf[uc_wcount] != uc_pbuf[uc_wcount])
		{
			break;
		}
	}
	if(uc_wcount != uc_count)
	{
		uc_rtv = 1;
	}
	Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
}
/*
@brief 写入三码数据
*/
void JQ_UID_PWD_Bind(void)
{
	uint8_t uc_rtv = 0;
	uint8_t uc_ack;
	uint8_t uc_count = 0;
	uint8_t uc_optbuf[16];
	uint32_t ul_write_mask = 0;
	
	if(JQXT_Test_IsNeedBind() == 0)
	{
		Checker_MaskResult(0,checker_runcfg.task_info.runindex);
    return;
	}
	
	uc_ack = JQ_ReadOTP(CHECKER_NET_ID,0x03,12,(uint8_t*)uc_optbuf);
	if(uc_ack < 1)
	{
		uc_rtv = 1;
		Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
		return;
	}
	JQ_EnWOTP();
	JQ_EnWOTP();
	for(uc_count = 0; uc_count < 8; uc_count++)
	{
		if((checker_runcfg.writeuid[uc_count] & uc_optbuf[uc_count]) != uc_optbuf[uc_count])
		{
			uc_rtv = 1;
			Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
			return;
			
		}
		if(checker_runcfg.writeuid[uc_count] != uc_optbuf[uc_count])
		{
			ul_write_mask |= ((0x01ul)<<uc_count);
		}
		
	}
	for(uc_count = 0; uc_count < 4; uc_count++)
	{
		if((checker_runcfg.writepwd[uc_count] & uc_optbuf[uc_count+8]) != uc_optbuf[uc_count+8])
		{
			uc_rtv = 1;
			Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
			return;
			
		}
		if(checker_runcfg.writepwd[uc_count] != uc_optbuf[uc_count+8])
		{
			ul_write_mask |= ((0x01ul)<<(uc_count+8));
		}
	}
	rt_memcpy(uc_optbuf,checker_runcfg.writeuid,8);
	rt_memcpy(uc_optbuf+8,checker_runcfg.writepwd,4);
	for(uc_count = 0; uc_count < 12; uc_count++)
	{
		if(ul_write_mask & 0x01)
		{
			uc_ack =  JQ_WriteOTP(0x03+uc_count,1,&uc_optbuf[uc_count]);
			if(uc_ack != 1)
			{
				break;
			}
		}
		ul_write_mask >>= 1;
	}
	if(uc_count != 12)
	{
		uc_rtv = 1;
	}
	Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
}
/*
@brief UID PWD 验证
*/
void JQ_Verify_UID_PWD(void)
{
	uint8_t uc_ack;
	uint8_t auc_uid_temp[8];
	uint8_t auc_pwd_temp[4];
	uint8_t uc_state;
	
	if(JQXT_Test_IsNeedBind() == 0)
	{
		Checker_MaskResult(0,checker_runcfg.task_info.runindex);
    return;
	}
	
	JQ_ScanUIDBegin();
	if(checker_runcfg.params[0] > 0)
	{
		JQ_FreeBack_Prapare(1);
	}
	uc_ack = JQ_ScanReadUID(CHECKER_NET_ID,auc_uid_temp);
	if(uc_ack < 1)
	{
		Checker_MaskResult(1,checker_runcfg.task_info.runindex);
		return;
	}
	for(uc_ack = 0; uc_ack < 4; uc_ack++)
	{
		auc_pwd_temp[uc_ack] = checker_runcfg.writepwd[3-uc_ack];
	}
	JQ_VerifyPWD(auc_pwd_temp);
	uc_state = 0;
	uc_ack = JQ_ReadState(CHECKER_NET_ID,&uc_state);
	if((uc_state & 0x40) == 0)
	{
		Checker_MaskResult(1,checker_runcfg.task_info.runindex);
		return;
	}
	for(uc_ack = 0; uc_ack < 8; uc_ack++)
	{
		if(checker_runcfg.writeuid[uc_ack] != auc_uid_temp[7-uc_ack])
		{
			break;
		}
	}
	if(uc_ack != 8)
	{
		Checker_MaskResult(1,checker_runcfg.task_info.runindex);
	}else{
		Checker_MaskResult(0,checker_runcfg.task_info.runindex);
	}
}
/*
@breif 测量电容电压差
@param0 两次测量间隔 0.1s
@rtv0   电压差值
*/
void JQ_Test_CapVoltage(void)
{
	uint16_t us_capv1;
	
	
	POWER_OFF;
	Power_SetSampleCurrentRange(Checker_OnLine_Sample_R);
	HMOS_FAST_DISCHG;
	HMOS_SWITCH_GND;
	delay_os_ms(1000);
	us_capv1 = AD_SampleCap(checker_runcfg.params[0]);
	POWER_ON;
	delay_os_ms(500);
	JQBUS_ON
	Power_SetSampleCurrentRange(Current_Max);
	
	Checker_MaskResult(0,checker_runcfg.task_info.runindex);
	Checker_SetRtv(&us_capv1,checker_runcfg.rtv_count);
	
}
/*
@breif OTP 读写使能
*/

void JQ_Test_EnOTPW(void)
{
	JQ_EnWOTP();
	Checker_MaskResult(0,checker_runcfg.task_info.runindex);
}
/* 
@breif  写模块版本 前提是要使能OTP (ENWOTP)
@param0 模块版本号
*/
void JQ_Test_WriteVersion(void)
{
	uint8_t uc_rtv = 0;
	uint8_t uc_ack;
	uint8_t uc_temp = 0;
	uint8_t uc_write = checker_runcfg.params[0] & 0x1F;
	
	uc_ack = JQ_ReadOTP(CHECKER_NET_ID,20,1,(uint8_t*)&uc_temp);
	if(uc_ack < 1)
	{
		uc_rtv = 1;
		Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
		return;
	}
	if((uc_temp & 0x1F) == uc_write)
	{
		uc_rtv = 0;
		Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
		return;
	}
	uc_temp |= uc_write;
	if((uc_temp & 0x1F) != uc_write)
	{
		uc_rtv = 1;
		Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
		return;
	}
	JQ_EnWOTP();
	JQ_EnWOTP();
	
	 uc_ack =  JQ_WriteOTP(20,1,(uint8_t*)&uc_temp);
	if(uc_ack != 1)
	{
		uc_rtv = 1;
		Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
		return;
	}
	uc_write = uc_temp;
	uc_ack = JQ_ReadOTP(CHECKER_NET_ID,20,1,(uint8_t*)&uc_temp);
	if(uc_ack < 1)
	{
		uc_rtv = 1;
	}
	if(uc_temp != uc_write)
	{
		uc_rtv = 1;
	}
	Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
}
/*
@brief 获取版本号

*/
void JQ_Test_ReadVersion(void)
{
	uint16_t us_temp = 0xFF;
	uint8_t uc_ack;
	uint8_t uc_rtv = 0;
	uc_ack = JQ_ReadOTP(CHECKER_NET_ID,20,1,(uint8_t*)&us_temp);
	if(uc_ack < 1)
	{
		uc_rtv = 1;
	}
	us_temp &= 0x1F;
	Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
	Checker_SetRtv(&us_temp,checker_runcfg.rtv_count);
}

/*
@brief 写入OTP数据
@param0 OTP起始地址
@param1 缓存首地址
@param2 写入长度
*/
void JQ_Test_WriteFacBuff(void)
{
	uint8_t uc_rtv = 0;
	uint8_t uc_ack;
	uint8_t uc_otpAddr = checker_runcfg.params[0];
	uint8_t uc_bufIndex = checker_runcfg.params[1];
	uint8_t uc_writeCount = checker_runcfg.params[2];
	uint8_t uc_count = 0;
	uint8_t uc_wcount ;
	uint8_t ul_temp[4];
	//Checker_FacBuf 验证合法性
	if(0 != Checker_FacBufCheck())
	{
		uc_rtv = 1;
		Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
		return;
	}
	JQ_EnWOTP();
	JQ_EnWOTP();
	for(uc_count = 0;  uc_count < uc_writeCount;uc_count++,uc_otpAddr++,uc_bufIndex++)
	{
		uc_ack = JQ_ReadOTP(CHECKER_NET_ID,uc_otpAddr,1,ul_temp);
		if(uc_ack < 1)
		{
			uc_rtv = 2;
			Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
			return;
		}
		if(Checker_FacBuf[uc_bufIndex+2] == ul_temp[0])
		{
			continue;
		}
		if(ul_temp[0] != 0)
		{
			if((ul_temp[0] & Checker_FacBuf[uc_bufIndex+2]) != ul_temp[0])//OTP不能由1变成0
			{
				uc_rtv = 3;
				Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
				return;
			}
		}
		
		uc_wcount = JQ_WriteOTP(uc_otpAddr,1,&Checker_FacBuf[uc_bufIndex+2]);
		if(uc_wcount != 1)
		{
			uc_rtv = 4;
			Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
			return;
		}
		
	}
	uc_rtv = 0;
	Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
	return;
}

/*
@brief 验证OTP内部与缓存比较
@param0 OTP起始地址
@param1 缓存首地址
@param2 验证长度
*/
void JQ_Test_VerifyFacBuff(void)
{
	uint8_t uc_rtv = 0;
	uint8_t uc_ack;
	uint8_t uc_otpAddr = checker_runcfg.params[0];
	uint8_t uc_bufIndex = checker_runcfg.params[1];
	uint8_t uc_verifyCount = checker_runcfg.params[2];
	uint8_t uc_count = 0;
	uint8_t ul_temp[4];
	if(0 != Checker_FacBufCheck())
	{
		uc_rtv = 1;
		Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
		return;
	}
	for(uc_count = 0;  uc_count < uc_verifyCount;uc_count++)
	{
		uc_ack = JQ_ReadOTP(CHECKER_NET_ID,uc_otpAddr,1,ul_temp);
		if((uc_ack < 1) || (Checker_FacBuf[uc_bufIndex+2] != ul_temp[0]))
		{
			uc_rtv = 2;
			Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
			return;
		}
		uc_bufIndex++;
		uc_otpAddr++;		
	}
	uc_rtv = 0;
	Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
	return;
}



/*rc{ 
读延时，与otp中的值相比，不同则此任务失败

}*/
void JQ_Test_VerifyDelay(void)
{
	uint8_t ul_temp[4]={0};
	uint8_t uc_ack=0,uc_rtv=0;
	uint16_t us_delaytime=0xffff,us_temp;
  uc_ack = JQ_ReadOTP(CHECKER_NET_ID,15,2,ul_temp);
	if(uc_ack<2) {uc_rtv=1;goto end;}
	uc_ack |= JQ_ReadDelay(CHECKER_NET_ID,&us_delaytime);
	if(uc_ack<2) {uc_rtv=2;goto end;}
	if((((us_delaytime >> 8) & 0x0FF)==ul_temp[0])&&
    (((us_delaytime) & 0x0FF)==ul_temp[1]))
  {
    
  }else{
    uc_rtv=3;goto end;
  }
  end:
	Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
}
/*
@brief 切换总线极性
@par0 从一个极性切换到另一个极性的间隔
@par1 从正极性切换到负极性为一个循环，循环的次数
@rtv1 返回最后一次总线电流 单位0.1uA
*/
void JQ_Test_Toggle(void)
{
	uint16_t ul_cur[2];
	uint16_t interval_ms = checker_runcfg.params[0];
	uint16_t times = checker_runcfg.params[1];
  for(int i=0;i<times;i++)
  {
    JQBUS_W_1
    delay_ms(interval_ms);
    JQBUS_W_0
    delay_ms(interval_ms);
  }
	JQBUS_W_1
	delay_ms(20);
	Checker_MaskResult(0,checker_runcfg.task_info.runindex);
	Checker_SetRtv(ul_cur,checker_runcfg.rtv_count);
}




/*rc{ 
写入流水号，使用读改写
par0,par1,流水号，小端存储
}*/
void JQ_Test_WriteSN(void)
{
	uint8_t uc_rtv = 0;
	uint8_t uc_ack;
	uint8_t uc_otpAddr = 20;
	uint8_t uc_writeCount = 4;
  // 缓存开大一点防止数据越界
	typedef union{
    uint8_t arr[6];
    uint32_t data;
  }temp_def;
  temp_def temp={0};
  uint32_t sn=0;
	JQ_EnWOTP();
	JQ_EnWOTP();
	for(int i = 0;  i < uc_writeCount;i++)
	{
		uc_ack = JQ_ReadOTP(CHECKER_NET_ID,uc_otpAddr+i,1,temp.arr+i);
		if(uc_ack < 1)
		{
			uc_rtv = 1;
      goto end;
		}
  }
  
  sn=checker_runcfg.params[0]|(checker_runcfg.params[1]<<16);
  if(sn>=134217728)
  {
    // 如果流水号超过了2^27 则失败
    uc_rtv=2;
    goto end;
  }
  // 流水号域如果有值且不为要设置的流水号则失败
  if((temp.data&(~0x1f))!=0){
    if((temp.data>>5)!=sn){
      uc_rtv=3;
    }
    goto end;
  }
  temp.data=temp.data|(sn<<5);
	for(int i = 0;  i < uc_writeCount;i++)
	{
    uc_ack = JQ_WriteOTP(uc_otpAddr+i,1,temp.arr+i);
    if(uc_ack != 1)
    {
      uc_rtv = 4;
      goto end;
    }
		
	}
	end:
	Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
	return;
}



/*rc{ 
校验流水号
par0,par1,流水号，小端存储
ret，校验失败则此任务失败
rtv，返回读取的流水号数据
}*/
void JQ_Test_ReadSN(void)
{
	uint8_t uc_rtv = 0;
	uint8_t uc_ack;
	uint8_t uc_otpAddr = 20;
	uint8_t uc_writeCount = 4;
  // 缓存开大一点防止数据越界
	typedef union{
    uint8_t arr[6];
    uint32_t data;
  }temp_def;
  temp_def temp={0};
  uint32_t sn=0;
	JQ_EnWOTP();
	JQ_EnWOTP();
	for(int i = 0;  i < uc_writeCount;i++)
	{
		uc_ack = JQ_ReadOTP(CHECKER_NET_ID,uc_otpAddr+i,1,temp.arr+i);
		if(uc_ack < 1)
		{
			uc_rtv = 1;
      goto end;
		}
  }
  
  sn=checker_runcfg.params[0]|(checker_runcfg.params[1]<<16);
  if(sn>=134217728)
  {
    // 如果流水号超过了2^27 则失败
    uc_rtv=2;
    goto end;
  }
  // 流水号域如果不为要设置的流水号则失败
  temp.data>>=5;
  if((temp.data)!=sn){
    uc_rtv=3;
  }
  
	end:
	Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
	Checker_SetRtv((uint16_t *)&temp,checker_runcfg.rtv_count);
	return;
}






/*rc{ 
写入固定延时
par0,延时信息
}*/
void JQ_Test_WriteDelay(void)
{
	uint8_t uc_rtv = 0;
	uint8_t uc_ack;
	uint8_t uc_otpAddr = 15;
	uint8_t uc_writeCount = 2;
  // 缓存开大一点防止数据越界
	typedef union{
    uint8_t arr[4];
    uint16_t data;
  }temp_def;
  temp_def temp={0};
  uint16_t delay=0;
  delay=checker_runcfg.params[0];
	JQ_EnWOTP();
	JQ_EnWOTP();
	for(int i = 0;  i < uc_writeCount;i++)
	{
		uc_ack = JQ_ReadOTP(CHECKER_NET_ID,uc_otpAddr+i,1,temp.arr+i);
		if(uc_ack < 1)
		{
			uc_rtv = 1;
      goto end;
		}
  }
  
  // 流水号域如果有值且不为要设置的延时值则失败
  if(temp.data!=0){
    if(temp.data!=delay){
      uc_rtv=2;
    }
    goto end;
  }
  temp.data=delay;
	for(int i = 0;  i < uc_writeCount;i++)
	{
    uc_ack = JQ_WriteOTP(uc_otpAddr+i,1,temp.arr+i);
    if(uc_ack != 1)
    {
      uc_rtv = 3;
      goto end;
    }
	}
	end:
	Checker_MaskResult(uc_rtv,checker_runcfg.task_info.runindex);
	return;
}








CheckerTask jqtaskArray[CHECKER_MAXID_COUNT] ={
Checker_PowerPrapare,	//0 电源准备  
JQ_Test_PowerOn,			//1 上电充能
JQ_Test_SetBusV,			//2 设置总线电压
JQ_Test_BaseCur,			//3 获取总线电流
JQ_Test_ScanUID,			//4 扫描UID
JQ_Test_PWCheck,			//5 密码验证
JQ_Test_ReadChipID,		//6 读取芯片代码
JQ_Test_OTPCheck,     //7 OTP检测
JQ_Test_FTCheck,			//8 工厂测试检测
JQ_Test_ReadState,		//9 读取状态
JQ_Test_WriteUserInfo,//10 写工厂信息
JQ_Test_ChgEnergy			,//11 充能统计
JQ_Test_CheckDAC			,//12 充电电压检测
Checker_WaitDelay			,//13 延时等待
JQ_Test_SetDelay			,//14 设置延时
JQ_Test_ReadDelay			,//15 读取延时
JQ_Test_ClkTrim				,//16 时钟校准
JQ_Test_Discharge			,//17 放电
JQ_Test_Reset					,//18 复位
JQ_Test_BootEn				,//19 起爆使能
JQ_Test_BoomEnergy		,//20 起爆充能
JQ_Test_EnCommEndCur	,//21 使能通讯末电流采集
JQ_Test_GetCommEndCur	,//22 获取通讯末电流
JQ_Test_WriteOTP			,//23 写OTP
JQ_Test_ReadOTP				,//24	读OTP
JQ_Test_ClearBoom			,//25 清除起爆计数
JQ_Test_PowerOff			,//26 关总线
JQ_Test_WriteBuf2OTP  ,//27 将缓存区数据写入OTP
JQ_UID_PWD_Bind				,//28 三码写入错误
JQ_Verify_UID_PWD			,//29 三码验证错误
JQ_Test_CapVoltage		,//30 测量电容压差
Checker_ResistorSample,//31 测量桥丝阻值
JQ_Test_EnOTPW				,//32 使能OTP写
JQ_Test_WriteVersion  ,//33 写模块版本
JQ_Test_ReadVersion   ,//34 读取版本号
JQ_Test_WriteFacBuff  ,//35 写缓存数据
JQ_Test_VerifyFacBuff ,//36 验证缓存数据
JQ_Test_VerifyDelay   ,//37 读取延时值和otp数据相比
JQ_Test_Toggle        ,//38 切换总线极性
CheckerExt_CalcErr    ,//39 计算异常
CheckerExt_Repeat     ,//40 重新执行任务
CheckerExt_SetUID     ,//41 设置uid数据到小板
CheckerExt_Slot       ,//42 任务插槽
CheckerExt_SetCbv     ,//43 设置电阻校准值
JQ_Test_WriteSN       ,//44 写入流水号
JQ_Test_ReadSN        ,//45 读取流水号
JQ_Test_WriteDelay    ,//46 写固定延时
(void*)0							//数组结束
};

