#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "platform_interface.h"
#include "base_core_user.h"
#include "base_core.h"
#include "function_interface.h"

#ifdef CORE_DEBUG
/*
*此文件仅仅用于基站内核固件的调试;
*实现思想：定义一段内存用于记录想要调试的数据，利用bushound发送命令读取对应内存段的数据;
*2020.05.20 根据李外定的usb调试协议，重新整理!!
*/


/*20200606乐教乐学错题debug,监测内容是键盘协议3.2.11 ANStype=7,8;
键盘编号为1-100;(必须!!!!)
在普通检测基础上，增加了多题型检测!!!
ff 81 xx	;xx=题目的个数,查看接收的总体情况
ff 82 xx 	;xx=题目的个数,查看基站发送给键盘的ack总体情况
ff 88 aa bb cc dd xx; 
	aabbccdd是要查询的十进制键盘SN的具体情况;
	xx =0,查询某个键盘默认参数
	xx =1,查询接收id错误的具体数据
	xx =2,查询接收内容错误的具体数据;
*/
	
/*	20200622 VOXM433 
200只voxm pad 平板;
检测接收到的键盘和发送给sdk的键盘次数

*/




//void realview_sprintf(unsigned char *scr,unsigned char mode);
void realview_sprintf(unsigned short *scr,unsigned char mode);
void core_debug__get_special_keypad_info(unsigned char *sn_dec);
void core_debug__get_all_keypad_info(unsigned char mode);

//-------------------------------------------
//Don't modify next three define !!
#define 	DBG_CMD_LEN				8			//记录sdk 命令的个数

#define 	DBG_ERRBUF_LEN		30		//最大记录错误键盘个数
#define		MONITOR_CNT				100		//实际监测键盘的个数
#define 	TILT_CNT					201//31//40//检测题数

#ifdef 	_20200622_VOXM_
#define 	DBG_BUF_LEN				201		//最大记录键盘个数
#else
#define 	DBG_BUF_LEN				101		//最大记录键盘个数
#endif




#ifdef 	_DBG_ID_KP	//检测ID键盘
//keypad record
struct keypad_STR{
	 unsigned short rx[DBG_BUF_LEN];			//接收到的键盘，次数？
	 unsigned short ack[DBG_BUF_LEN];			//对键盘的回应, 次数？
	 unsigned short tx_sdk[DBG_BUF_LEN];	//上报给SDK的次数
	 unsigned short sdk_ack[DBG_BUF_LEN];	//被sdk确认的次数
	
	#ifdef _20200606_LEJIAO
	unsigned char tile[DBG_BUF_LEN][TILT_CNT];//检测题型
	#endif

};

//error record
struct error_STR{
	//id
	 unsigned char rx_id[DBG_ERRBUF_LEN];	//出错的id
	 unsigned char rx_id_cnt;							//出错的个数	
	 unsigned char ack_id[DBG_ERRBUF_LEN];
	 unsigned char ack_id_cnt;
	
	#ifdef _20200606_LEJIAO //乐教乐学
	unsigned char rx_content_cnt;
	unsigned char content[DBG_ERRBUF_LEN][8];
	unsigned char rx_content_id[DBG_ERRBUF_LEN];	
	unsigned char tile_id[DBG_ERRBUF_LEN];
	unsigned char tile_id_cnt;
	#endif
};

#endif 

struct debug_STR{
	unsigned char sw_flag;	//此调试功能开关
	unsigned char cmd_type[DBG_CMD_LEN];	//记录来自sdk的命令		
	void (*send_data)(unsigned char *);	//void (*send_data)(unsigned char *data_,unsigned char len);
	
	unsigned char vote_status;
	
	#ifdef _DBG_ID_KP
	//unsigned char kp_cnt;	//special //??
	struct keypad_STR kp;	
	struct error_STR err;
	#endif
};


/*
* delay function*/
void core_debug_delay_ms( unsigned short time )
{
    unsigned short  i = 0;
    while( time-- ){
			i = 33400;
			while( i-- );
    }
}

/*
* usb发送函数*/
static void core_debug_send_data(unsigned char *buf)
{	
	platform.base_send_data_to_pc(buf,64);
}


/*
* 初始化 core debug结构体
*/
struct debug_STR core_debug={
	.sw_flag=0,
	.send_data = core_debug_send_data,
	.cmd_type =0,	
};	


/*
初始化debug,清理所有变量为0 
called by system init or applicaiton startup;
*/
void core_debug__init(void)
{
	unsigned short i,j;	
	//if(core_debug.sw_flag==0) return;//没有开启此功能，直接返回

	//sdk cmd type
	for(i=0;i<DBG_CMD_LEN;i++)
		core_debug.cmd_type[i] =0;	

	#ifdef _DBG_ID_KP
	//keypad 
	for(i=0;i<DBG_BUF_LEN;i++){
		core_debug.kp.rx[i] =0;
		core_debug.kp.ack[i] =0;
		core_debug.kp.tx_sdk[i] =0;
		core_debug.kp.sdk_ack[i] =0;
		//6sn
	}	
//	core_debug.kp_cnt=0;
	
	//error 
	for(i=0;i<DBG_ERRBUF_LEN;i++){
		core_debug.err.rx_id[i] =0;
		core_debug.err.ack_id[i]=0;		
	}		
	core_debug.err.ack_id_cnt =0;
	core_debug.err.rx_id_cnt =0;
	#endif
	
	
	#ifdef _DBG_VOICE_KP
	_debug_voice_kp__init_all_parameter();
	#endif
	
	
	#ifdef _20200606_LEJIAO
	//内容错误检测
	core_debug.err.rx_content_cnt =0;
	for(i=0;i<DBG_ERRBUF_LEN;i++){
		core_debug.err.rx_content_id[i] =0;
		mem_set(core_debug.err.content[i],8,0);	
	}
	
	//题型检测
	core_debug.err.tile_id_cnt=0;
	for(i=0;i<DBG_ERRBUF_LEN;i++){
		core_debug.err.tile_id[i]=0;
	}
	
	for(i=0;i<DBG_BUF_LEN;i++){
		mem_set(core_debug.kp.tile[i],TILT_CNT,0);		
	}
	#endif 
	
	
	//如下可根据实际需求增加
//	core_debug.sw_flag =1; //开启此调试功能//???
	
}



/*
*	vote status =空闲 or 投票中
* 	0 ->空闲
*	other -> voting 
*/
void core_debug__set_vote_status(unsigned char stat)
{
		core_debug.vote_status = stat;
}

unsigned char core_debug__get_vote_status(void)
{
	return core_debug.vote_status;
}





/*
处理调试命令主函数
called by main loop 
*/
void _debug_main_loop(void)
{
	unsigned char i,j,count,tmp[DBG_BUF_LEN];
	
	if(core_debug.sw_flag ==0) return;		//没有开启此功能
	if(core_debug.cmd_type[0]==0) return;	//没有命令就返回	
//	memset(tmp,0,DBG_BUF_LEN);	//init tmp=0
	
	switch(tmp[0]=core_debug.cmd_type[0]){
		
		//1.0, open usb debug switch
		case 0xff:
			memset(tmp,' ',32);
			sprintf( (char *)(tmp),"Open usb debug ok!!");
			platform.base_send_data_to_pc(tmp,32);
			break;
		//1.1,clear all parameter
		case 0xF0:	
			core_debug__init();
			memset(tmp,' ',32);
			sprintf( (char *)(tmp),"Init all parameter OK");	
			platform.base_send_data_to_pc(tmp,32);				
			break;		
		
		//2,调试键盘丢题 --获取所有键盘状态
		//rx and ack  between base and keypad;
		case 0x81://基站接收到的键盘和接收次数
		case 0x82://基站确认过的键盘和确认次数
		//case 0x83:	//获取指定键盘 最后提交的数据	
		//case 0x84:	//获取数据出错的键盘
		case 0x85:	//获取上报给sdk的键盘
		case 0x86:	//获取被sdk确认的键盘
		//case 0x87:	//查看基站是否有滞留的投票数据
		core_debug__get_all_keypad_info(core_debug.cmd_type[0]);
		break;
		
		//2.1,调试键盘丢题 --获取指定键盘的细节状态
		case 0x88:	//查询指定SN的键盘数据
		#ifdef _DBG_VOICE_KP	
		_debug_voice_kp__app_get_keypad_debug_info(core_debug.cmd_type+1);
		#else
		core_debug__get_special_keypad_info(core_debug.cmd_type+1);	
		#endif 
		break;

		//3 用于function debug的入口
		case 0xA0:
			function._debug__function_enter(core_debug.cmd_type+1);				
			break;		
		
		case 0xB0:
			keypad_battery_test_enter(core_debug.cmd_type+1);
			break;

		//add other type
		default:
			break;
	}//sw

	core_debug.cmd_type[0]=0;//清零，避免重复发送
}
#endif 



/* 
* app 命令接口函数 -与sdk的通信接口
* called by usb communicatoin
*/
void core_debug_enter(unsigned char *pc)
{
		#ifdef CORE_DEBUG
		//a,fisrt byte must be 0xff;
		if( pc[0]!=0xFF)	return;
		//b,copy data 
		mem_cpy(pc+1,core_debug.cmd_type,DBG_CMD_LEN);
		//c,special command-debug turn on;
		if( (core_debug.cmd_type[0] ==0xff) &&(core_debug.cmd_type[1] ==0x00) &&
			(core_debug.cmd_type[2] ==0xff) &&(core_debug.cmd_type[3] ==0x00) &&
			(core_debug.cmd_type[4] ==0xff) &&(core_debug.cmd_type[5] ==0x00) &&
			(core_debug.cmd_type[6] ==0xff) &&(core_debug.cmd_type[7] ==0x00) ){
				core_debug.sw_flag =1; //开启此调试功能
		}
		#endif
}








//--------------------------------------------------------------------------------------
#ifdef CORE_DEBUG

/*
*/
void _debug_core__load_1line__var2string(unsigned char line,unsigned char *in,unsigned char in_len, unsigned char *out)
{
	unsigned char i,str[17];
	memset(out+(line<<4),0,16);
	for(i=0;i<in_len;i++)
		str[i] = in[i];
	str[16] ='\0';
	sprintf( (char *)(out+(line<<4)),"%s",str );	
	
}

/* 以十进制 打印变量数据  
*/
void _debug_core__load_1line__var2dec(unsigned char line,unsigned char *in,unsigned char in_len, unsigned char *out)
{
	unsigned char i;
	unsigned int dec=0;
	memset(out+(line<<4),0,16);
	for(i=0;i<in_len;i++)
		dec += in[i]<<( (in_len-1-i)<<3);
	sprintf( (char *)(out+(line<<4)),"%d",dec);		
}



/*
* 20201017 优化，暂未测试验证
*/
/* --------------------------------------
//直观的以ASII吗列表表示100只键盘接收，确认，报错，上送SDK, SDK确认等状态
* 每行显示16个字符 
* 此函数一个键盘只能显示一个字符 !!! 获取所有键盘的 大体状态;
	30 keypads in
   123456789A   
1  1111111111
2  1111110111  //表示17号缺失!! 
3
4
5
6
7
8
9
A
*/
void core_debug__get_all_keypad_info(unsigned char mode)
{
	unsigned char i,j,tmp[512],count=0;
	unsigned short *scr=NULL;
	unsigned char line16[16];
	char first_line[32]=" -Null%d- ";
	
	//1, get source 
	#ifdef 	_DBG_ID_KP
	switch(mode){	//第一行
		case 0x81://基站接收到的键盘和接收次数
			scr =core_debug.kp.rx;
			strcpy(first_line ," %003d keypads in");
			break;
		case 0x82://基站确认过的键盘和确认次数
			scr =core_debug.kp.ack;
			strcpy(first_line ,"%003d keypads ack");
			break;
		case 0x83:	//获取指定键盘 最后提交的数据
			break;
		case 0x84:	//获取数据出错的键盘
			break;
		case 0x85:	//获取上报给sdk的键盘
			scr=core_debug.kp.tx_sdk;
			strcpy(first_line ,"%003d send to SDK");
			break;
		case 0x86:	//获取被sdk确认的键盘
			scr=core_debug.kp.sdk_ack;
			strcpy(first_line ," %003d ack by SDK");
			break;
		case 0x87:	//查看基站是否有滞留的投票数据
			break;
		default:	break;
	}//sw	
	#endif 
	
	//2, print //第二行
	_debug_core__load_1line__var2string(1,(unsigned char*)"   123456789A   ",16,tmp);	
	#ifdef 	_20200622_VOXM_
	for(i=0;i<20;i++){	//第三行开始....
	#else
	for(i=0;i<10;i++){	//第三行开始....
	#endif
		memset(line16,0,16);	//clear
		line16[0] = ' ';
		line16[1]= 0x30+ ((i<10)?i:i-10) ;
		line16[2] = ' ';
		for(j=1;j<11;j++){
			if(scr[i*10+j]) {
				line16[2+j]='1';
				count++;
			}//if
		}//for
		_debug_core__load_1line__var2string(2+i,line16,16,tmp);		
	}//for		

	//3, 第一行 
	sprintf( (char *)(tmp),first_line,count);
	
	tmp[389]=0xa5;	//调试时，bushound监测到此数据串就停下来，便于观察！！
	tmp[390]=0x5a;
	tmp[391]=0xa5;	
	platform.base_send_data_to_pc(tmp+0,512);	
}


#if 0
#define		DBG_DISP_SIZE		400


void realview_sprintf(unsigned short *scr,unsigned char mode)
{
	unsigned char j,count;
	unsigned char tmp[DBG_DISP_SIZE];
	unsigned short i;
	
	count=0;
	memset(tmp,' ',DBG_DISP_SIZE);
		
	sprintf( (char *)(tmp+16),"   123456789A   ");//第二行
	
	#ifdef 	_20200622_VOXM_
	for(i=0;i<20;i++){	//第三行开始....
	#else
	for(i=0;i<10;i++){	//第三行开始....
	#endif	
		//每行开始0-2个字符
		tmp[32+i*16+0]=' ';			//空格		
		tmp[32+i*16+1]= 0x30+ ((i<10)?i:i-10) ;//0x30+i;	//行号
		tmp[32+i*16+2]=' ';			//空格
		//每行的3-12字节
		for(j=1;j<11;j++){//keypad id/sn start from 1;
			#ifdef _20200606_LEJIAO
			if(scr[i*10+j]>= core_debug.cmd_type[1]) {
				//tmp[32+i*16+j+2]='0'+scr[i*10+j];//打印每个键盘的次数//0-9是数字可以直接转化成字符
				//sprintf((char *)(tmp[32+i*16+j+2]),"%x",scr[i*10+j]);
				tmp[32+i*16+j+2]='1';
				count++;
			}
			#else
			if(scr[i*10+j]) {
				tmp[32+i*16+j+2]='1';//0'+scr[i*10+j];//打印每个键盘的次数//0-9是数字可以直接转化成字符
				count++;
			}			
			#endif 						
		}//for
		//每行的13-15字节
		tmp[32+i*16+13]=0;tmp[32+i*16+14]=0;tmp[32+i*16+15]=0;//每行未用到的数据清零，便于清晰查看
	}//for
	
	switch(mode){	//第一行
		case 0x81:
			sprintf( (char *)(tmp)," %003d keypads in",count);
			break;
		case 0x82:
			sprintf( (char *)(tmp),"%003d keypads ack",count);
			break;
		case 0x83:
			//sprintf( (char *)(tmp)," %003d keypads in",count);
			break;
		case 0x84:
			//sprintf( (char *)(tmp)," %003d keypads in",count);
			break;
		case 0x85:
			sprintf( (char *)(tmp),"%003d send to SDK",count);
			break;
		case 0x86:
			sprintf( (char *)(tmp)," %003d ack by SDK",count);
			break;
		case 0x87:
			//sprintf( (char *)(tmp)," %003d keypads in",count);
			break;
		default:
			break;
	}//sw
	
	tmp[389]=0xa5;	//调试时，bushound监测到此数据串就停下来，便于观察！！
	tmp[390]=0x5a;
	tmp[391]=0xa5;	
	platform.base_send_data_to_pc(tmp+0,512);	
}
#endif

#if 0
/*------------------------------------------------------------
此函数解决debug时 显示字符
1 line: inquired keypad SN
2 line: keypad list count
3 line: 
app 发送查询某个键盘信息的命令
基站收到命令后:在keypad list中搜索键盘，如果存在,复制该键盘数据上报给app;
*/
void core_debug__get_special_keypad_info(unsigned char *sn_dec)
{
	struct link_node_STR *node;			

	unsigned char i,j,count;
	unsigned char tmp[256];
	unsigned char sn[4];
	unsigned char temp_cnt;
	
	count=0;
	memset(tmp,' ',256);	
	Dec_to_Hex(sn_dec,4,sn);
	
	//1 line
	sprintf( (char *)(tmp),"SN: ");
	sprintf( (char *)(tmp+4),"%010d",(sn[0]<<24)+(sn[1]<<16)+(sn[2]<<8)+sn[3]);

	if( (sn[0]<<24)+(sn[1]<<16)+(sn[2]<<8)+sn[3] > MONITOR_CNT )
		sprintf( (char *)(tmp+16),"Err:SN nonexst!"); //2 line
	else{
		#ifdef _20200606_LEJIAO
		if(sn_dec[4]==0){ //sn号后面的参数，默认查键盘各个参数
			//2 line 接收到的键盘数据包个数
			sprintf( (char *)(tmp+16),"RXKP:");
			sprintf( (char *)(tmp+16+5),"%011d",core_debug.kp.rx[sn[3]]);		
			//3 line 基站ack的次数
			sprintf( (char *)(tmp+32),"ACKKP:");
			sprintf( (char *)(tmp+32+7),"%09d",core_debug.kp.ack[sn[3]]);	
			
			//4 line 接收错误
			sprintf( (char *)(tmp+48),"rxideer:");
			temp_cnt =0;
			for(i=0;i<core_debug.err.rx_id_cnt;i++){
				if(core_debug.err.rx_id[i] ==sn[3])temp_cnt++;			
			}
			sprintf( (char *)(tmp+48+10),"%05d",temp_cnt);	

			//5 line ack
			sprintf( (char *)(tmp+64),"ackerr:");
			temp_cnt =0;
			for(i=0;i<core_debug.err.ack_id_cnt;i++){
				if(core_debug.err.ack_id[i] ==sn[3])temp_cnt++;			
			}			
			sprintf( (char *)(tmp+64+10),"%05d",temp_cnt);	

			//6 line 
			sprintf( (char *)(tmp+80),"rxconteer:");
			temp_cnt =0;
			for(i=0;i<core_debug.err.rx_content_cnt;i++){
				if(core_debug.err.rx_content_id[i] ==sn[3]){
					if( temp_cnt+1>10) return; //最大10行
					sprintf( (char *)(tmp+96+temp_cnt*16+4),"cont");
					mem_cpy(core_debug.err.content[i],tmp+96+temp_cnt*16+8,8);	
					temp_cnt++;
				}		
			}//for				
			sprintf( (char *)(tmp+80+7),"%05d",temp_cnt);	
		}
		else if(sn_dec[4]==1){//查题目
			//2 line 接收到的键盘数据包个数
			sprintf( (char *)(tmp+16),"tileerrcnt:");
			//sprintf( (char *)(tmp+16+5),"%011d",core_debug.kp.rx[sn[3]]);				
			//3 line 基站ack的次数
			//sprintf( (char *)(tmp+32),"ACKKP:");
			sprintf( (char *)(tmp+32),"%05d",core_debug.err.tile_id_cnt);
			//line 4
			temp_cnt=0;
			for(i=1;i<=core_debug.err.tile_id_cnt;i++){
					sprintf( (char *)(tmp+48+i*3),"%03d",core_debug.err.tile_id[i]);				
			}//for			
			//sprintf( (char *)(tmp+48),"losetile");
			
//			//line5
//			temp_cnt=0;
//			for(i=1;i<=TILT_CNT;i++){
//				if(core_debug.kp.tile[sn[3]][i]==0){
//					sprintf( (char *)(tmp+64+5+temp_cnt*2),"%02d",i);
//					temp_cnt++;
//				}	
//			}//for
//			sprintf( (char *)(tmp+64),"%04d",temp_cnt);	
		}
		else if(sn_dec[4]==2){//查键盘的错误id的具体情况
			//line 2
			sprintf( (char *)(tmp+16),"losetile");
			//line 3
			temp_cnt=0;
			for(i=1;i<=TILT_CNT;i++){
				//if( (core_debug.kp.tile[sn[3]][i]==0) && (32+5+temp_cnt*3+3 <255) ){
					//sprintf( (char *)(tmp+32+5+temp_cnt*3),"%03d",i);
				if( (core_debug.kp.tile[sn[3]][i]==0) && (32+5+temp_cnt*4+3 <255) ){	//两个之间增加空格便于观察
					sprintf( (char *)(tmp+32+5+temp_cnt*4),"%03d ",i);	
					temp_cnt++;
				}	
			}//for
			sprintf( (char *)(tmp+32),"%04d",temp_cnt);	
		}	
		#endif



		#ifdef 	_20200622_VOXM_
		if(sn_dec[4]==0){ //sn号后面的参数，默认查键盘各个参数
			//2 line 接收到的键盘数据包个数
			sprintf( (char *)(tmp+16),"RXKP:");
			sprintf( (char *)(tmp+16+5),"%011d",core_debug.kp.rx[sn[3]]);		
			//3 line 基站ack的次数
			sprintf( (char *)(tmp+32),"ACKKP:");
			sprintf( (char *)(tmp+32+7),"%09d",core_debug.kp.ack[sn[3]]);	
			
			//4 line 接收错误
			sprintf( (char *)(tmp+48),"rxideer:");
			temp_cnt =0;
			for(i=0;i<core_debug.err.rx_id_cnt;i++){
				if(core_debug.err.rx_id[i] ==sn[3])temp_cnt++;			
			}
			sprintf( (char *)(tmp+48+10),"%05d",temp_cnt);	

			//5 line ack
			sprintf( (char *)(tmp+64),"ackerr:");
			temp_cnt =0;
			for(i=0;i<core_debug.err.ack_id_cnt;i++){
				if(core_debug.err.ack_id[i] ==sn[3])temp_cnt++;			
			}			
			sprintf( (char *)(tmp+64+10),"%05d",temp_cnt);	

			//6 line 
			sprintf( (char *)(tmp+80),"TxSDK:");
			sprintf( (char *)(tmp+80+7),"%09d",core_debug.kp.tx_sdk[sn[3]]);	
		}		
		#endif
			
		
	}
			
	tmp[189]=0xa5;	//调试时，bushound监测到此数据串就停下来，便于观察！！
	tmp[190]=0x5a;
	tmp[191]=0xa5;
	
	platform.base_send_data_to_pc(tmp+0,256);	
}

#else

/*
* 20201017 优化，暂未测试验证
*/
void core_debug__get_special_keypad_info(unsigned char *sn_dec)
{
	unsigned char sn[4];
	unsigned char tmp[512];	
	unsigned char temp_cnt,i;
	
	Dec_to_Hex(sn_dec,4,sn);
	_debug_core__load_1line__var2string(0,(unsigned char*)"search SN:   ",16,tmp);	
	_debug_core__load_1line__var2string(1,sn,4,tmp);		
	
	if( (sn[0]<<24)+(sn[1]<<16)+(sn[2]<<8)+sn[3] > MONITOR_CNT ){
		_debug_core__load_1line__var2string(2,(unsigned char*)"Err:SN nonexst!",16,tmp);	
		return;
	}	

	if(sn_dec[4]==0){ //sn号后面的参数，默认查键盘各个参数
		#ifdef _DBG_ID_KP
		//rx keypad count
		_debug_core__load_1line__var2string(3,(unsigned char*)"RXKP:",16,tmp);
		_debug_core__load_1line__var2string(4,(unsigned char*)&core_debug.kp.rx[sn[3]],2,tmp);	//2 byte conver print short?
		//rx keypad count
		_debug_core__load_1line__var2string(5,(unsigned char*)"ACKKP:",16,tmp);
		_debug_core__load_1line__var2string(6,(unsigned char*)&core_debug.kp.ack[sn[3]],2,tmp);		
		//rx error--beyond the max id/sn
		_debug_core__load_1line__var2string(7,(unsigned char*)"RX error:",16,tmp);	
		temp_cnt =0;
		for(i=0;i<core_debug.err.rx_id_cnt;i++){
			if(core_debug.err.rx_id[i] ==sn[3])temp_cnt++;			
		}			
		_debug_core__load_1line__var2string(8,&temp_cnt,1,tmp);	
		//ack error 
		_debug_core__load_1line__var2string(9,(unsigned char*)"ACK error:",16,tmp);	
		temp_cnt =0;
		for(i=0;i<core_debug.err.ack_id_cnt;i++){
			if(core_debug.err.ack_id[i] ==sn[3])temp_cnt++;			
		}			
		_debug_core__load_1line__var2string(10,&temp_cnt,1,tmp);
		#endif
		
		#ifdef _20200606_LEJIAO
		//rx content error :从所有的错误记录中查找当前id
		_debug_core__load_1line__var2string(11,(unsigned char*)"RX content error:",16,tmp);	
		temp_cnt =0;
		for(i=0;i<core_debug.err.rx_content_cnt;i++){
			if(core_debug.err.rx_content_id[i] ==sn[3]){
				_debug_core__load_1line__var2string(12+i,core_debug.err.content[i],8,tmp);
				temp_cnt++;
			}		
		}//for
		_debug_core__load_1line__var2string(12+i,(unsigned char*)"RX con err cnt:",16,tmp);
		_debug_core__load_1line__var2string(13+i,&temp_cnt,1,tmp);
		#endif
	}
	
	#ifdef _20200606_LEJIAO	
	else if(sn_dec[4]==1){//查题目
		//题目出错的个数及出错题号
		_debug_core__load_1line__var2string(3,(unsigned char*)"tile err cnt:",16,tmp);
		_debug_core__load_1line__var2string(4,&core_debug.err.tile_id_cnt,1,tmp);		
		for(i=1;i<=core_debug.err.tile_id_cnt;i++)
			_debug_core__load_1line__var2string(4+i,&core_debug.err.tile_id[i],1,tmp);		
	}
	else if(sn_dec[4]==2){//查键盘的错误id的具体情况
		_debug_core__load_1line__var2string(3,(unsigned char*)"Lose tile:",16,tmp);		
		temp_cnt=0;
		for(i=1;i<=TILT_CNT;i++){
			if( core_debug.kp.tile[sn[3]][i]==0){	//两个之间增加空格便于观察
				_debug_core__load_1line__var2string(4+i,&i,1,tmp);//sprintf( (char *)(tmp+32+5+temp_cnt*4)," %03d ",i);	
				temp_cnt++;
			}	
		}//for
		_debug_core__load_1line__var2string(4+temp_cnt,(unsigned char*)"Lose tile cnt:",16,tmp);
		_debug_core__load_1line__var2string(5+temp_cnt,&temp_cnt,1,tmp);	
	}
	#endif 
	
	tmp[189]=0xa5;	//调试时，bushound监测到此数据串就停下来，便于观察！！
	tmp[190]=0x5a;
	tmp[191]=0xa5;
	
	platform.base_send_data_to_pc(tmp+0,512);			
}

#endif








//------------------------------ 记录相关数据的函数 (被外部调用) -----------------------------
/*
记录接收到的键盘的id/sn
called by rx keypad 
input: id/sn  
由于需要适配各种不同的键盘，键盘报告的数据格式也不一样，所以基本上很难通用!!!
*/
void core_debug__record_rx_keypad(const unsigned char *rx_kp)
{	
		unsigned char kp_id;
		if(core_debug.sw_flag ==0) return;
		
		#ifdef _20200606_LEJIAO
		kp_id = rx_kp[6];//see protocol
	
		if( (rx_kp[3]!=0)||(rx_kp[4]!=0)||(rx_kp[5]!=0)||(kp_id==0) ||(kp_id>MONITOR_CNT) ){ //id/SN 超出范围
			if( core_debug.err.rx_id_cnt <DBG_ERRBUF_LEN)//避免溢出
				core_debug.err.rx_id[core_debug.err.rx_id_cnt++] = kp_id;	//记录id号出错问题
		}
		else{						
			//开始判断接收到的键盘内容!!!!	,广播申请算作一次正常接收数据，因为要与ack次数对应		
			if( ( (rx_kp[2]==12)&&(rx_kp[9]==4))  ||  ( (rx_kp[12] ==0x1f)&& mem_cmp_const(rx_kp+13,7,0xff) ) ){
				core_debug.kp.rx[kp_id]++;
			
				//检测题型
				if( (rx_kp[11] ==0) || (rx_kp[11] >TILT_CNT) ){
					//error
					core_debug.err.tile_id[core_debug.err.tile_id_cnt]= rx_kp[11];
					core_debug.err.tile_id_cnt++;
				}
				else{
					core_debug.kp.tile[kp_id][rx_kp[11]]++;
				}
			}
			else{
				if( core_debug.err.rx_content_cnt <DBG_ERRBUF_LEN){//避免溢出
					core_debug.err.rx_content_id[core_debug.err.rx_content_cnt] =kp_id; 			//记录内容出错时的id					
					mem_cpy(rx_kp+12,core_debug.err.content[core_debug.err.rx_content_cnt],8);//记录出错的内容
					core_debug.err.rx_content_cnt++;
				}
			}					
		}
		#elif	defined(_20200622_VOXM_)
		kp_id = rx_kp[3];//see protocol
		//error
		if( (rx_kp[2]!=0) ||(rx_kp[3]==0) ){
			if( core_debug.err.rx_id_cnt <DBG_ERRBUF_LEN)//避免溢出
				core_debug.err.rx_id[core_debug.err.rx_id_cnt++] = kp_id;	//记录id号出错问题			
		}
		else{
			core_debug.kp.rx[kp_id]++;			
		}

		#elif defined(_DBG_ID_KP)	
		kp_id = rx_kp[3];//see protocol
		//error
		if( (rx_kp[2]!=0) ||(rx_kp[3]==0) ){
			if( core_debug.err.rx_id_cnt <DBG_ERRBUF_LEN)//避免溢出
				core_debug.err.rx_id[core_debug.err.rx_id_cnt++] = kp_id;	//记录id号出错问题			
		}
		else{
			core_debug.kp.rx[kp_id]++;			
		}	
		#endif 
}


/*
记录ack键盘的id
called base ack function 
input: keypad id; 
ack的格式是固定的，所以可以通用!!!!
*/
void core_debug__record_ack_keypad(unsigned char *ack_kp )
{		
		#ifdef _DBG_ID_KP
		unsigned char kp_id;
		if(core_debug.sw_flag ==0) return;
		if( (ack_kp[0]==0)&&(ack_kp[1]==0)&&(ack_kp[2]==0)&&(ack_kp[3]==0) ) return;
		//if(kp_id==0) return ;//没有数据ack发的就是0,所以不算是错误!!
		kp_id = ack_kp[3];
		if( (ack_kp[0]!=0)||(ack_kp[1]!=0)||(ack_kp[2]!=0)||(ack_kp[3]==0) ){ //if(kp_id>MONITOR_CNT){ //id/SN 超出范围
			if( core_debug.err.ack_id_cnt <DBG_ERRBUF_LEN)//避免溢出
				core_debug.err.ack_id[core_debug.err.ack_id_cnt++] = kp_id;
		}
		else{
			core_debug.kp.ack[kp_id]++;	
		}
		#endif
}



/*
*记录基站发送投票数据给pc的情况
* 键盘各个业务功能的数据格式各有不同，所以很难做到通用处理!!!
*/
void core_debug__tx_pc(unsigned char *id)
{
	#ifdef	_20200622_VOXM_
	unsigned char kp_id = id[1];
	if( (id[0]!=0) || (id[1] ==0) ){
			//core_debug.err.	
	}
	else{
		core_debug.kp.tx_sdk[kp_id]++;			
	}	
	#endif
}



#endif

//-------------------------------------------------  end ------------------------------------------------------------------

