#include "stdafx.h"
#include <string.h>
//#include "DataInit.h"
#include "ZLG600_DLL.h"
#include "Win32COM_DLL.h"

//卡片回应数据存放数据
unsigned char ucATQ[2];
unsigned char ucUID[10];
unsigned char ucUIDLen;
unsigned char ucSAK;
extern unsigned char ModulFormat;
//内部函数声明

static unsigned char OnBUTTONRequest();      //请求卡
static unsigned char OnBUTTONAnti1();		 //一级防冲突
static unsigned char OnBUTTONSelect1();      //一级卡选择
static unsigned char OnBUTTONAnti2();        //二级防冲突
static unsigned char OnBUTTONSelect2();      //二级卡选择
static void Uart_Send_Command(unsigned char *DataBuff,unsigned char length);
static void Uart_Receive_Data(unsigned char *DataBuff,unsigned char length);    //如果客户是用中断方式接收串口数据则不需要这个函数,只需将下面的Uart_INT宏定义改为0即可
static void BCC_CLA(void);
extern unsigned char  Init_NDEF_Message_TLV(const char *pName,const char *pAddr,unsigned char *pSendData);
 unsigned char  Data_FormatChange(unsigned char Mode,unsigned char *PDin);
 unsigned int BCC_NEW(const unsigned char *p, unsigned char length);
//全局变量
unsigned char g_ucSerBuf[MAX_SER_SIZE];		// 串行数据缓冲区
unsigned char g_ucSEQ;						// 包号,见通信协议
unsigned char UIDset[4];					//用于保存7字节UID的高4字节
unsigned char UIDNum=4;                     //记录UID的字节数
#define Uart_INT     1
unsigned char ZLG522init_OK=0;              //ZLG522初始化成功标志
CString Uartinitstr;
char    Uartinitnum;

unsigned char     Format = 0;              // 0:旧帧格式    1：新帧格式
unsigned char    LocallAddr=0xB2;          //模块地址
unsigned char    SlotIndex=0x00;           //卡槽索引
unsigned char    SMCSeq=0x00;              //数据帧包号
//////////////////////////////////////////////////////////////////////////
////////                      内部函数                  //////////////////
//////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数功能:    计算BCC校验值
// 输入参数:    -		
// 输出参数:    -
// 返 回 值:    无
///////////////////////////////////////////////////////////////////////////////////////////////////
void BCC_CLA(void)
{
    unsigned char i,BCC;
	
	BCC = 0;
	for(i=0; i<(g_ucSerBuf[FRAMELEN]-2); i++)
		BCC ^= g_ucSerBuf[i];
	g_ucSerBuf[g_ucSerBuf[FRAMELEN]-2] = ~BCC;
	g_ucSerBuf[g_ucSerBuf[FRAMELEN]-1] = ETX;	
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数功能:    串口数据发送函数，由客户自行完成
// 输入参数:    无	
// 输出参数:    无
// 返 回 值:    无
///////////////////////////////////////////////////////////////////////////////////////////////////
void Uart_Send_Command(unsigned char *DataBuff,unsigned char length)
{
	//SendoutData(DataBuff,length);
	if(ModulFormat ==1 ) 
	{
      length = Data_FormatChange(OLD_TO_NEW,DataBuff);
	}
	SendData(DataBuff,length);
	
	//length表明g_ucSerBuf数组中需要发送的数据长度，客户只要把g_ucSerBuf数组中的前length个数据发送出去就行了
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数功能:    串口数据发送函数，由客户自行完成
// 输入参数:    无	
// 输出参数:    无
// 返 回 值:    无
///////////////////////////////////////////////////////////////////////////////////////////////////
void Uart_Receive_Data(unsigned char *DataBuff,unsigned char length)
{
	//把串口接收到的数据放到g_ucSerBuf数组中就行了。 
	RecevieData(DataBuff,length);
	if(ModulFormat ==1 ) 
	{
		length = Data_FormatChange(NEW_TO_OLD,DataBuff);
	}
	
}

/*****************************************************************
****卡片激活由以下几个步骤完成
****
******************************************************************/
///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型:    unsigned char PiccRequest(unsigned char ucReqCode,unsigned char *pATQ)
// 函数功能:    请求
// 输入参数:    unsigned char ucReqCode			// 请求代码		
// 输出参数:   
// 返 回 值:    命令执行结果
///////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char OnBUTTONRequest() //第一步
{
	// TODO: Add your control notification handler code here
												// 卡片激活操作
//	PiccRequest(REQ_STD);                       //请求准备状态的卡片
	g_ucSerBuf[CMDTYPE] = CMD_TYPE_TYPE_A|g_ucSEQ;// 命令类型与包号组成一个字节
	g_ucSerBuf[COMMAND] = 'A';
	g_ucSerBuf[LENGTH] = 1;
	g_ucSerBuf[DATA] = REQ_STD;
	g_ucSEQ += 0x10;					          //包号加	
	g_ucSerBuf[FRAMELEN] = g_ucSerBuf[LENGTH] + PRTCLEN;	//帧长度等于数据长度加协议长度
	
	BCC_CLA();									  //计算BCC校验值

	Uart_Send_Command(g_ucSerBuf,g_ucSerBuf[0]);
	Sleep(delaytime);
	#if(Uart_INT == 1)
	Uart_Receive_Data(g_ucSerBuf,100);
	#endif
	if(g_ucSerBuf[STATUS]==0x00)return CommandOk;
	else return RequestErr;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型:    unsigned char PiccAnticoll( unsigned char ucSelCode,unsigned char ucBcnt,
//											unsigned char *pUID)
// 函数功能:    防碰撞
// 输入参数:    unsigned char ucSelCode			// 防碰撞等级
//												// SELCODE1	0x93	等级1
//												// SELCODE2	0x95	等级2
//												// SELCODE3	0x97	等级3
//				unsigned char ucBcnt			// 已知卡号的位数，通常设置为0
//				unsigned char *pUID				// 已知的卡号，若不知道，则不用理会
// 输出参数:    unsigned char *pUID				// 卡号
// 返 回 值:    命令执行结果
///////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char OnBUTTONAnti1()  //第二步
{
	// TODO: Add your control notification handler code here
	//PiccAnticoll(SEL_CODE_LV1,0,ucUID);			//一级防碰撞
	g_ucSerBuf[CMDTYPE] = CMD_TYPE_TYPE_A;
	g_ucSerBuf[COMMAND] = 'B';
	g_ucSerBuf[LENGTH]  = 6;
	g_ucSerBuf[DATA] 	= SEL_CODE_LV1;
	g_ucSerBuf[DATA + 1] = 0;
	g_ucSEQ += 0x10;					          //包号加	
	g_ucSerBuf[FRAMELEN] = g_ucSerBuf[LENGTH] + PRTCLEN;	//帧长度等于数据长度加协议长度
	memcpy(&g_ucSerBuf[DATA + 2], ucUID, 4);
	
	BCC_CLA();									  //计算BCC校验值

	Uart_Send_Command(g_ucSerBuf,g_ucSerBuf[0]);
	Sleep(delaytime);
#if(Uart_INT == 1)
	Uart_Receive_Data(g_ucSerBuf,100);
	#endif
	if(g_ucSerBuf[STATUS]==0x00)return CommandOk;
	else return AnticollErr1;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型:    unsigned char PiccSelect(unsigned char ucSelCode,unsigned char *pUID,
//										 unsigned char *pSAK)
// 函数功能:    选择卡
// 输入参数:    unsigned char ucSelCode			// 选择(防碰撞等级)
//												// SELCODE1	0x93	等级1
//												// SELCODE2	0x95	等级2
//												// SELCODE3	0x97	等级3
//				unsigned char *pUID				// 卡号
// 输出参数:    unsigned char *pSAK				// 选择应答
// 返 回 值:    命令执行结果
///////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char OnBUTTONSelect1() //第三步
{
	// TODO: Add your control notification handler code here
	UIDNum=4;
	ucUID[0] = g_ucSerBuf[4];
	ucUID[1] = g_ucSerBuf[5];
	ucUID[2] = g_ucSerBuf[6];
	ucUID[3] = g_ucSerBuf[7];
	if(ucUID[0]==0x88) UIDNum=7;
	//PiccSelect(SEL_CODE_LV1,ucUID);				//一级卡选择
	g_ucSerBuf[CMDTYPE] = CMD_TYPE_TYPE_A;
	g_ucSerBuf[COMMAND] = 'C';
	g_ucSerBuf[LENGTH] = 5;
	g_ucSerBuf[DATA]   = SEL_CODE_LV1;
	memcpy(&g_ucSerBuf[DATA + 1], ucUID, 4);
	g_ucSEQ += 0x10;					          //包号加	
	g_ucSerBuf[FRAMELEN] = g_ucSerBuf[LENGTH] + PRTCLEN;	//帧长度等于数据长度加协议长度
	
	BCC_CLA();

	Uart_Send_Command(g_ucSerBuf,g_ucSerBuf[0]);
	Sleep(delaytime);
#if(Uart_INT == 1)
	Uart_Receive_Data(g_ucSerBuf,100);
	#endif
	if(g_ucSerBuf[STATUS]==0x00)return CommandOk;
	else return SelectErr1;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型:    unsigned char PiccAnticoll( unsigned char ucSelCode,unsigned char ucBcnt,
//											unsigned char *pUID)
// 函数功能:    防碰撞
// 输入参数:    unsigned char ucSelCode			// 防碰撞等级
//												// SELCODE1	0x93	等级1
//												// SELCODE2	0x95	等级2
//												// SELCODE3	0x97	等级3
//				unsigned char ucBcnt			// 已知卡号的位数，通常设置为0
//				unsigned char *pUID				// 已知的卡号，若不知道，则不用理会
// 输出参数:    unsigned char *pUID				// 卡号
// 返 回 值:    命令执行结果
///////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char OnBUTTONAnti2()  //第四步
{
	// TODO: Add your control notification handler code here
	//PiccAnticoll(SEL_CODE_LV2,0,ucUID);			//二级防碰撞
	g_ucSerBuf[CMDTYPE] = CMD_TYPE_TYPE_A;
	g_ucSerBuf[COMMAND] = 'B';
	g_ucSerBuf[LENGTH]  = 6;
	g_ucSerBuf[DATA] 	= SEL_CODE_LV2;
	g_ucSerBuf[DATA + 1] = 0;
	g_ucSEQ += 0x10;					          //包号加	
	g_ucSerBuf[FRAMELEN] = g_ucSerBuf[LENGTH] + PRTCLEN;	//帧长度等于数据长度加协议长度
	memcpy(&g_ucSerBuf[DATA + 2], ucUID, 4);
	
	BCC_CLA();									  //计算BCC校验值

	Uart_Send_Command(g_ucSerBuf,g_ucSerBuf[0]);
	Sleep(delaytime);
#if(Uart_INT == 1)
	Uart_Receive_Data(g_ucSerBuf,100);
	#endif
	if(g_ucSerBuf[STATUS]==0x00)return CommandOk;
	else return AnticollErr2;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型:    unsigned char PiccSelect(unsigned char ucSelCode,unsigned char *pUID,
//										 unsigned char *pSAK)
// 函数功能:    选择卡
// 输入参数:    unsigned char ucSelCode			// 选择(防碰撞等级)
//												// SELCODE1	0x93	等级1
//												// SELCODE2	0x95	等级2
//												// SELCODE3	0x97	等级3
//				unsigned char *pUID				// 卡号
// 输出参数:    unsigned char *pSAK				// 选择应答
// 返 回 值:    命令执行结果
///////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char OnBUTTONSelect2()  //第五步
{
	// TODO: Add your control notification handler code here
	UIDset[0] = g_ucSerBuf[4];
	UIDset[1] = g_ucSerBuf[5];
	UIDset[2] = g_ucSerBuf[6];
	UIDset[3] = g_ucSerBuf[7];
	//PiccSelect(SEL_CODE_LV2,UIDset);			//二级卡选择
	g_ucSerBuf[CMDTYPE] = CMD_TYPE_TYPE_A;
	g_ucSerBuf[COMMAND] = 'C';
	g_ucSerBuf[LENGTH] = 5;
	g_ucSerBuf[DATA]   = SEL_CODE_LV2;
	memcpy(&g_ucSerBuf[DATA + 1], UIDset, 4);
	g_ucSEQ += 0x10;					          //包号加	
	g_ucSerBuf[FRAMELEN] = g_ucSerBuf[LENGTH] + PRTCLEN;	//帧长度等于数据长度加协议长度
	
	BCC_CLA();

	Uart_Send_Command(g_ucSerBuf,g_ucSerBuf[0]);
	Sleep(delaytime);
	#if(Uart_INT == 1)
	Uart_Receive_Data(g_ucSerBuf,100);
	#endif
	if(g_ucSerBuf[STATUS]==0x00)return CommandOk;
	else return SelectErr2;
}

//////////////////////////////////////////////////////////////////////////
////////                      ZLG522对外接口功能        //////////////////
//////////////////////////////////////////////////////////////////////////
BOOL  ZLG522S_Init(char ComNum, unsigned int uiBaudRate, unsigned int uiModuleType)
{

	Uartinitstr.Format("%d,n,8,1",uiBaudRate);
	Uartinitnum = ComNum;
	ZLG522init_OK = 1;
	return TRUE;
}

HANDLE  ZLG522S_Open(unsigned char *pErr,unsigned int uiModuleAdr)
{
	unsigned char statues=1;
	HANDLE m_handle=INVALID_HANDLE_VALUE;
	unsigned char Sex[]={0x20,0x20},RevDa[2]={0x00,0x00};
	CString  getinfo="06 01 41 00 B9 03";
	char times=3;
	if(ZLG522init_OK == 0){ m_handle = OpenComm(1,"19200,n,8,1");}//如果还未初始化串口，则先初始化串口
	else {m_handle = OpenComm(Uartinitnum,(LPCSTR)Uartinitstr);}
	if(m_handle!=INVALID_HANDLE_VALUE){
		do{
			SendData(Sex,1);
			Sleep(delaytime);
			SendData(Sex,1);
			Sleep(delaytime);
			RecevieData(RevDa,1);
			if(RevDa[0]==0x06){*pErr = 0;break;}
			else times--;
		}while(times!=0);
		//if(RevDa[0]!=0x06){
			//statues = SendString(getinfo);
				g_ucSerBuf[STATUS]=0x01;
			statues = GetDvcInfo(g_ucSerBuf);
			//Sleep(delaytime);
		
			//Uart_Receive_Data(g_ucSerBuf,100);
			if(statues==0x00) {return m_handle;*pErr = 0;}
			else CloseComm(m_handle);
	//	}
	}
	else {*pErr = 1;return INVALID_HANDLE_VALUE;} //如果是串口打开不成功就返回-1,错误代码pErr=1
	*pErr=2;                          //如果是模块通信不成功就返回2
	return INVALID_HANDLE_VALUE;    //
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型:	void ZLG522S_Exit(HANDLE hCtrl)
// 函数功能:	ZLG522S关闭退出
// 入口参数:	HANDLE hCtrl					// 通讯控制				
// 出口参数:	-
// 返 回 值:	-
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void  ZLG522S_Exit(HANDLE hCtrl)
{
	CloseComm(hCtrl);
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数功能:    利用读卡器激活卡片
// 输入参数:    UID  : 数组指针，用于存放获取到的卡片ID号
//              UIDlength:外部传入的用于存放UID长度的变量地址
// 输出参数:    无
// 返 回 值:    0x00:卡片激活成功，其它见ZLG600Driv.h中错误类型定义
///////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char  PICC_Active(unsigned char *UID,unsigned char *UIDlength)
{
	unsigned char status;
	 
	
	status = OnBUTTONRequest();            				 //请求卡
	if(status) return status;               
	status = OnBUTTONAnti1();                            //一级防碰撞
	if(status) return status;               
	status = OnBUTTONSelect1();                          //一级卡选择
	if(status) return status;               
	if(UIDNum==7){
		status = OnBUTTONAnti2();                            //二级防碰撞
		if(status) return status;               
		status = OnBUTTONSelect2();                          //二级卡选择
		if(status) return status;           
		
		ucUID[0]=ucUID[1];ucUID[1]=ucUID[2];ucUID[2]=ucUID[3];
		ucUID[3]=UIDset[0];ucUID[4]=UIDset[1];ucUID[5]=UIDset[2];
		ucUID[6]=UIDset[3];							//保存全部的UID
		memcpy(UID,ucUID,7);                        //保存UID
	}else{ //UID为4字节时
	    memcpy(UID,ucUID,4);	
	}
	*UIDlength = UIDNum;
	return CommandOk;                                    //以上命令都执行成功则表示卡片激活成功，接下来就可以进行卡片读写操作
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数功能:    制作蓝牙配对卡片
// 输入参数:    pName----蓝牙设备名称   (只可以是字母和数字的组合)
//              pAddr----蓝牙设备MAC地址(格式：AC:74:70:B0:F0:30)	      
// 输出参数:    无
// 返 回 值:    0x00:卡片激活成功，其它见ZLG600Driv.h中错误类型定义
// 修改：2013-12-27  添加了写入卡片数据正确性校验功能
///////////////////////////////////////////////////////////////////////////////////////////////////
/*unsigned char MYAPI Make_BluetoothCard(const char *pName,const char *pAddr)
{
	unsigned char  length,nPage,status,i;
	unsigned char  times = 0;
	unsigned char  Sendbuff[200]={0};		//定义长度 200的数组用于存放要写入卡片的数据
	unsigned char  Recevibuff[200]={0};    //定义接收数组，用于读取卡片内的数据，一遍校验正确性
	length =  Init_NDEF_Message_TLV(pName,pAddr,Sendbuff);
	if(length)
	{   //长度不为0，则输入信息正确
		//将设备名称和MAC地址转化为特定格式，并存放于g_ucSerBuf中，length指示有效数据字节数
		nPage = (length+1)/4;
		if((length+1)%4)nPage++;            //计算要占用的卡片数据页个数
		
		for(i = 0;i < nPage; )
		{
			status = UltraLightPiccWrite(5+i,&Sendbuff[i*4]);
			if(status){
				times++;
				if(times == 5){
				return MakeCardErr;
				break;
				}
			}else{
			i++;
			}
		}
		status = ReadCard_NPages(5,nPage,Recevibuff);  //将刚刚写入卡片的数据读出来，比较正确性
		if(status==0){  //读取数据成功
			if(memcmp(Recevibuff,Sendbuff,length))return CardDataCmpErr;       
			//比较写入的数据和读出的数据是否一致
		}
	}else{
		return BlueFormatErr;
	}
	
	return CommandOk;
}*/

//------------------------------读卡器基本操作----------------------------------//
//------------------------------------------------------------------------------//
///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型:    
// 函数功能:    获取设备型号及版本信息
// 输入参数:    无
//				
// 输出参数:    版本信息				// 卡号
// 返 回 值:    命令执行结果
///////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char  GetDvcInfo(unsigned char *DvcInfo)
{
	
	g_ucSerBuf[CMDTYPE] = 1;
	g_ucSerBuf[COMMAND] = 'A';
	g_ucSerBuf[LENGTH] = 0;
	g_ucSEQ += 0x10;					          //包号加	
	g_ucSerBuf[FRAMELEN] = g_ucSerBuf[LENGTH] + PRTCLEN;	//帧长度等于数据长度加协议长度
	BCC_CLA();
	
	Uart_Send_Command(g_ucSerBuf,g_ucSerBuf[0]);
	Sleep(delaytime);
#if(Uart_INT == 1)
	Uart_Receive_Data(g_ucSerBuf,100);
#endif
	if(g_ucSerBuf[STATUS]==0x00){
        memcpy(DvcInfo,&g_ucSerBuf[DATA],g_ucSerBuf[LENGTH]);
		return CommandOk;
	}
	else return ReadErr;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型:PiccActiveTypeA(	unsigned char mode,   保留字节，设置为0即可
//unsigned char Req_Code,                     0x26：~IDLE    0x52：~ALL
//unsigned char *Atq,
//unsigned char *Ats,
//unsigned char *PiccSnrLen,
//unsigned char *PiccUID	)
// 输出参数:    无
// 返 回 值:    0x00:命令执行成功，其它:失败
///////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char  PiccActiveTypeA(	unsigned char mode,
							  unsigned char Req_Code,
							  unsigned char *Atq,
							  unsigned char *Ats,
							  unsigned char *PiccSnrLen,
							  unsigned char *PiccSnr	)
{
	
	
	g_ucSerBuf[CMDTYPE] = 2;	   //
	g_ucSerBuf[COMMAND] = 'M';
	g_ucSerBuf[LENGTH] = 2;
	g_ucSerBuf[DATA] = 0;
	g_ucSerBuf[DATA+1] = Req_Code;
	g_ucSEQ += 0x10;					          //包号加	
	g_ucSerBuf[FRAMELEN] = g_ucSerBuf[LENGTH] + PRTCLEN;	//帧长度等于数据长度加协议长度
	
	BCC_CLA();
	
	Uart_Send_Command(g_ucSerBuf,g_ucSerBuf[0]);
	Sleep(delaytime);
#if(Uart_INT == 1)
	Uart_Receive_Data(g_ucSerBuf,100);
#endif
	if(g_ucSerBuf[STATUS]==0x00){
		*Atq = g_ucSerBuf[DATA];
		*(Atq+1) = g_ucSerBuf[DATA+1];
		*Ats = g_ucSerBuf[DATA+2];
		*PiccSnrLen = g_ucSerBuf[DATA+3];
		memcpy(PiccSnr,&g_ucSerBuf[DATA+4],*PiccSnrLen);
		return CommandOk;
	}
	else return ActiveCardErr;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数功能:    验证卡片密钥
// 输入参数:    KeyMode----密钥类型 KeyA或者KeyB 
//              *PiccUID----要验证的卡片的ID号存放地址
//              *Key    ----密钥存放地址
//              Block   ----要验证的块号	      
// 输出参数:    无
// 返 回 值:    0x00:命令执行成功，其它:失败
///////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char  PiccAuthKey(unsigned char KeyMode,unsigned char *PiccUID,unsigned char *Key,unsigned char Block)
{	
	g_ucSerBuf[CMDTYPE] = 2;
	g_ucSerBuf[COMMAND] = 'F';
	g_ucSerBuf[LENGTH] = 12;
	g_ucSerBuf[DATA] = KeyMode;
	memcpy(&g_ucSerBuf[DATA+1],PiccUID,4);
	memcpy(&g_ucSerBuf[DATA+5],Key,6);
	g_ucSerBuf[DATA+11] = Block;	
	g_ucSEQ += 0x10;					          //包号加	
	g_ucSerBuf[FRAMELEN] = g_ucSerBuf[LENGTH] + PRTCLEN;	//帧长度等于数据长度加协议长度
	
	BCC_CLA();
	
	Uart_Send_Command(g_ucSerBuf,g_ucSerBuf[0]);
	Sleep(delaytime);
#if(Uart_INT == 1)
	Uart_Receive_Data(g_ucSerBuf,100);
#endif
	if(g_ucSerBuf[STATUS]==0x00)return CommandOk;
	else return CardAuthErr;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型:    unsigned char PiccRead(unsigned char ucBlock)
// 函数功能:    Mifare读命令
// 入口参数:    unsigned char ucPage			; 读的页地址
//              unsigned char *pReadBuff        : 用于存放读取数据的数组指针
// 返 回 值:    -0:表示读取数据成功，  07：执行失败
// 说    明:	-   
///////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char  PiccRead(unsigned char ucPage,unsigned char *pReadBuff)
{
	g_ucSerBuf[CMDTYPE] = CMD_TYPE_TYPE_A;
	g_ucSerBuf[COMMAND] = 'G';
	g_ucSerBuf[LENGTH] = 1;
	g_ucSerBuf[DATA] = ucPage;
	g_ucSEQ += 0x10;					          //包号加	
	g_ucSerBuf[FRAMELEN] = g_ucSerBuf[LENGTH] + PRTCLEN;	//帧长度等于数据长度加协议长度
	BCC_CLA();
	
	Uart_Send_Command(g_ucSerBuf,g_ucSerBuf[0]);
	Sleep(delaytime);
	#if(Uart_INT == 1)
	Uart_Receive_Data(g_ucSerBuf,100);
	#endif
	if(g_ucSerBuf[STATUS]==0x00){
        memcpy(pReadBuff,&g_ucSerBuf[DATA],16);
		return CommandOk;
	}
	else return ReadErr;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型:    unsigned char PiccWrite(unsigned char Block,unsigned char *Bfr)
// 函数功能:    Mifare卡写数据命令
// 入口参数:    unsigned char Block			; 写数据的目的块地址
//              unsigned char *Bfr          ; 要写的数据存放缓冲区地址
// 返 回 值:    -0:表示读取数据成功，  WriteErr：执行失败
// 说    明:	-   
///////////////////////////////////////////////////////////////////////////////////////////////////

unsigned char  PiccWrite(unsigned char Block,unsigned char *Bfr)
{	
	g_ucSerBuf[CMDTYPE] = 2;
	g_ucSerBuf[COMMAND] = 'H';
	g_ucSerBuf[LENGTH] = 17;
	g_ucSerBuf[DATA] = Block;
	memcpy(&g_ucSerBuf[DATA+1],Bfr,16);
	g_ucSEQ += 0x10;					          //包号加	
	g_ucSerBuf[FRAMELEN] = g_ucSerBuf[LENGTH] + PRTCLEN;	//帧长度等于数据长度加协议长度
	
	BCC_CLA();
	
	Uart_Send_Command(g_ucSerBuf,g_ucSerBuf[0]);
	Sleep(delaytime);
#if(Uart_INT == 1)
	Uart_Receive_Data(g_ucSerBuf,100);
#endif
	if(g_ucSerBuf[STATUS]==0x00)return CommandOk;
	else return WriteErr;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型:    unsigned char UltraLightPiccWrite( unsigned char ucBlock, unsigned char *pBfr)
// 函数功能:    UltraLight写命令
// 入口参数:    unsigned char ucBlock			; 写入的块地址。
//				unsigned char *pBfr				; 4字节写数据缓冲区首址。
// 出口参数:    -
// 返 回 值:    -
// 说    明:	-   
///////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char  UltraLightPiccWrite(unsigned char ucBlock,unsigned char *pBuf)
{
	
	g_ucSerBuf[CMDTYPE] = CMD_TYPE_TYPE_A;
	g_ucSerBuf[COMMAND] = 'I';
	g_ucSerBuf[LENGTH] = 5;
	g_ucSerBuf[DATA] = ucBlock;
	memcpy(&g_ucSerBuf[DATA+1], pBuf, 4);
	
	g_ucSEQ += 0x10;					          //包号加	
	g_ucSerBuf[FRAMELEN] = g_ucSerBuf[LENGTH] + PRTCLEN;	//帧长度等于数据长度加协议长度
	BCC_CLA();
	
	Uart_Send_Command(g_ucSerBuf,g_ucSerBuf[0]);
	Sleep(delaytime);
	#if(Uart_INT == 1)
	Uart_Receive_Data(g_ucSerBuf,100);
	#endif
	if(g_ucSerBuf[STATUS]==0x00)return CommandOk;
	else return WriteErr;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数功能:    读取卡片内指定数量的页数据
// 输入参数:    StartPage----要读取的页面首地址   (只可以是字母和数字的组合)
//              Num      ----要读取的页面数量	
//                    
// 输出参数:    unsigned char *RevBuff     : 从卡片中读到的数据存放于此地址中
// 返 回 值:    0x00:命令执行成功，07:读取页面执行失败
///////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char  ReadCard_NPages(unsigned char StartPage,unsigned char Num,unsigned char *RevBuff)
{
	unsigned char Statues;
	char i,Readtimes;
	Readtimes = Num/4;
	if(Num%4)Readtimes++;			//算出需要调用PiccRead函数的次数，一次读取4页
	for(i = 0;i<Readtimes;i++)
	{
		Statues = PiccRead(StartPage+4*i,RevBuff+16*i);
	
	}
	return Statues;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型:unsigned char PiccValue(unsigned char Mode,unsigned char Block,unsigned char *Value,unsigned char TransBlock)
// 输入参数:    unsigned char Mode----值操作类型
//                                    0xC0---减值
//                                    0xC1---加值
//                                    0xC2---复制
//              unsigned char Block----值操作目的块号  ，注意进行值操作的块必须先具备值块的格式
//                                     卡块号（1 字节）： S50（0 ～63） 
//                                                        S70（0 ～255） 
//                                                        PLUS CPU 2K（0 ～127） 
//                                                        PLUS CPU 4K（0 ～255）
//              unsigned char *Value,  值（4 字节有符号数，低字节在先）
//              unsigned char TransBlock   ----值操作结果存放的块号（1 字节）	      
// 输出参数:    无
// 返 回 值:    0x00:命令执行成功，其它:失败
///////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char  PiccValue(unsigned char Mode,unsigned char Block,unsigned char *Value,unsigned char TransBlock)
{
	g_ucSerBuf[CMDTYPE] = 2;
	g_ucSerBuf[COMMAND] = 'J';
	g_ucSerBuf[LENGTH] = 7;
	g_ucSerBuf[DATA] = Mode;
	g_ucSerBuf[DATA+1] = Block;
	memcpy(&g_ucSerBuf[DATA+2],Value,4);
	g_ucSerBuf[DATA+6] = TransBlock;
	g_ucSEQ += 0x10;					          //包号加	
	g_ucSerBuf[FRAMELEN] = g_ucSerBuf[LENGTH] + PRTCLEN;	//帧长度等于数据长度加协议长度
	
	BCC_CLA();
	
	Uart_Send_Command(g_ucSerBuf,g_ucSerBuf[0]);
	Sleep(delaytime);
#if(Uart_INT == 1)
	Uart_Receive_Data(g_ucSerBuf,100);
#endif
	if(g_ucSerBuf[STATUS]==0x00)return CommandOk;
	else return CardAuthErr;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型:unsigned char PCDLoadKey(unsigned char KEYAB,unsigned char SecNr,unsigned char *Key)
// 输入参数:   unsigned char KEYAB----密钥类型 KeyA或者KeyB
//                                    
//              unsigned char SecNr----密钥编号 
//                                  ZLG522内部只有4个密钥存放区，所以编号只能是0,1,2,3
//                                  不过KeyA和KeyB都可以存放四个，所以一共是8个密钥存放区
//                                     
//              unsigned char *Key------密钥	      
// 输出参数:    无
// 返 回 值:    0x00:命令执行成功，其它:失败
///////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char  PCDLoadKey(unsigned char KEYAB,unsigned char SecNr,unsigned char *Key)
{	
	g_ucSerBuf[CMDTYPE] = 1;
	g_ucSerBuf[COMMAND] = 'E';
	g_ucSerBuf[LENGTH] = 8;
	g_ucSerBuf[DATA] = KEYAB;
	g_ucSerBuf[DATA+1] = SecNr;
	memcpy(&g_ucSerBuf[DATA+2],Key,6);
	g_ucSEQ += 0x10;					          //包号加	
	g_ucSerBuf[FRAMELEN] = g_ucSerBuf[LENGTH] + PRTCLEN;	//帧长度等于数据长度加协议长度
	
	BCC_CLA();
	
	Uart_Send_Command(g_ucSerBuf,g_ucSerBuf[0]);
	Sleep(delaytime);
#if(Uart_INT == 1)
	Uart_Receive_Data(g_ucSerBuf,100);
#endif
	if(g_ucSerBuf[STATUS]==0x00)return CommandOk;
	else return LoadKeyErr;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型:unsigned char PiccAuthE2(unsigned char KeyAB,unsigned char *PiccSnr,unsigned char SecNr,unsigned char Block)
// 输入参数:   unsigned char KeyAB----密钥类型 KeyA或者KeyB
//                                    
//              unsigned char *PiccSnr----卡片UID
//                                     
//              unsigned char SecNr------密钥编号（密钥在模块内部的编号）
//              unsigned char Block------卡片块号
//                                             S50（0 ～63） 
//                                             S70（0 ～255） 
//                                             PLUS CPU 2K（0 ～127） 
//                                             PLUS CPU 4K（0 ～255）	      
// 输出参数:    无
// 返 回 值:    0x00:命令执行成功，其它:失败
///////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char  PiccAuthE2(unsigned char KeyAB,unsigned char *PiccSnr,unsigned char SecNr,unsigned char Block)
{	
	g_ucSerBuf[CMDTYPE] = 2;
	g_ucSerBuf[COMMAND] = 'E';
	g_ucSerBuf[LENGTH] = 7;
	g_ucSerBuf[DATA] = KeyAB;
	memcpy(&g_ucSerBuf[DATA+1],PiccSnr,4);
	g_ucSerBuf[DATA+5] = SecNr;
	g_ucSerBuf[DATA+6] = Block;	

	g_ucSEQ += 0x10;					          //包号加	
	g_ucSerBuf[FRAMELEN] = g_ucSerBuf[LENGTH] + PRTCLEN;	//帧长度等于数据长度加协议长度
	
	BCC_CLA();
	
	Uart_Send_Command(g_ucSerBuf,g_ucSerBuf[0]);
	Sleep(delaytime);
#if(Uart_INT == 1)
	Uart_Receive_Data(g_ucSerBuf,100);
#endif
	if(g_ucSerBuf[STATUS]==0x00)return CommandOk;
	else return CardAuthEEErr;	
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型:unsigned char PiccHalt()         将卡片挂起
// 输入参数:   无      
// 输出参数:    无
// 返 回 值:    0x00:命令执行成功，其它:失败
///////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char  PiccHalt()
{
	g_ucSerBuf[CMDTYPE] = 2;
	g_ucSerBuf[COMMAND] = 'D';
	g_ucSerBuf[LENGTH] = 0;
	
	g_ucSEQ += 0x10;					          //包号加	
	g_ucSerBuf[FRAMELEN] = g_ucSerBuf[LENGTH] + PRTCLEN;	//帧长度等于数据长度加协议长度
	
	BCC_CLA();
	
	Uart_Send_Command(g_ucSerBuf,g_ucSerBuf[0]);
	Sleep(delaytime);
#if(Uart_INT == 1)
	Uart_Receive_Data(g_ucSerBuf,100);
#endif
	if(g_ucSerBuf[STATUS]==0x00)return CommandOk;
	else return PICCHaltErr;	
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型:unsigned char PiccHalt()
// 输入参数:   unsigned char _1ms   :  n即是关闭天线信号n毫秒
//                                 0:  表示一直关闭天线信号     
// 输出参数:    无
// 返 回 值:    0x00:命令执行成功，其它:失败
///////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char  PiccReset(unsigned char _1ms)
{
	g_ucSerBuf[CMDTYPE] = 2;
	g_ucSerBuf[COMMAND] = 'L';
	g_ucSerBuf[LENGTH] = 1;
	g_ucSerBuf[DATA] = _1ms;
	
	g_ucSEQ += 0x10;					          //包号加	
	g_ucSerBuf[FRAMELEN] = g_ucSerBuf[LENGTH] + PRTCLEN;	//帧长度等于数据长度加协议长度
	
	BCC_CLA();
	
	Uart_Send_Command(g_ucSerBuf,g_ucSerBuf[0]);
	Sleep(delaytime);
#if(Uart_INT == 1)
	Uart_Receive_Data(g_ucSerBuf,100);
#endif
	if(g_ucSerBuf[STATUS]==0x00)return CommandOk;
	else return PICCHaltErr;	
}

//------------------------------读卡器基本操作----------------------------------//
//------------------------------------------------------------------------------//
///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型:    
// 函数功能:    设置模块通信波特率
// 输入参数:    无
//				
// 输出参数:    版本信息				// 卡号
// 返 回 值:    命令执行结果
///////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char  PCDSetDAUD(unsigned char BDRNum)
{
	
	g_ucSerBuf[CMDTYPE] = 1;
	g_ucSerBuf[COMMAND] = 'H';
	g_ucSerBuf[LENGTH] = 1;
	g_ucSerBuf[DATA] = BDRNum;
	g_ucSEQ += 0x10;					          //包号加	
	g_ucSerBuf[FRAMELEN] = g_ucSerBuf[LENGTH] + PRTCLEN;	//帧长度等于数据长度加协议长度
	BCC_CLA();
	
	Uart_Send_Command(g_ucSerBuf,g_ucSerBuf[0]);
	Sleep(delaytime);
#if(Uart_INT == 1)
	Uart_Receive_Data(g_ucSerBuf,100);
#endif
	if(g_ucSerBuf[STATUS]==0x00){
		return CommandOk;
	}
	else return ReadErr;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型:    
// 函数功能:    设置模块新旧帧格式
// 输入参数:    unsigned char WFormat：0x01---新帧格式
//                                     0x00---旧帧格式
//				
// 输出参数:    版本信息				// 卡号
// 返 回 值:    命令执行结果
///////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char  PCDSetFormat(unsigned char WFormat)
{
	
	g_ucSerBuf[CMDTYPE] = 1;
	g_ucSerBuf[COMMAND] = 'K';
	g_ucSerBuf[LENGTH] = 1;
	g_ucSerBuf[DATA] = WFormat;
	g_ucSEQ += 0x10;					          //包号加	
	g_ucSerBuf[FRAMELEN] = g_ucSerBuf[LENGTH] + PRTCLEN;	//帧长度等于数据长度加协议长度
	BCC_CLA();
	
	Uart_Send_Command(g_ucSerBuf,g_ucSerBuf[0]);
	Sleep(delaytime);
#if(Uart_INT == 1)
	Uart_Receive_Data(g_ucSerBuf,100);
#endif
	if(g_ucSerBuf[STATUS]==0x00){
		return CommandOk;
	}
	else return ReadErr;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型:    
// 函数功能:    设置模块工作模式
// 输入参数:    unsigned char Mode, 模块工作模式
//                 UCHAR Addr      ,模块地址
//				
// 输出参数:    版本信息				// 卡号
// 返 回 值:    命令执行结果
///////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char  PCDSetWordMode(unsigned char Mode,unsigned char MAddr)
{
	
	g_ucSerBuf[CMDTYPE] = 1;
	g_ucSerBuf[COMMAND] = 'U';
	g_ucSerBuf[LENGTH] = 2;
	g_ucSerBuf[DATA] = Mode;
	g_ucSerBuf[DATA+1] = MAddr;
	g_ucSEQ += 0x10;					          //包号加	
	g_ucSerBuf[FRAMELEN] = g_ucSerBuf[LENGTH] + PRTCLEN;	//帧长度等于数据长度加协议长度
	BCC_CLA();
	
	Uart_Send_Command(g_ucSerBuf,g_ucSerBuf[0]);
	Sleep(50);
#if(Uart_INT == 1)
	Uart_Receive_Data(g_ucSerBuf,100);
#endif
	if(g_ucSerBuf[STATUS]==0x00){
		return CommandOk;
	}
	else return ReadErr;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型:    void Data_FormatChange(unsigned char Mode,unsigned char *PDin)
// 函数功能:    将数据做新旧帧格式转换
// 输入参数:    unsigned char Mode  转化方向
//                                  1: 旧帧转新帧  OLD_TO-NEW
//                                  0: 新帧转旧帧  NEW_TO_OLD
//        		unsigned char *PDin  要转化的数据
// 输出参数:    unsigned char *PDin			//转化后的数据
// 返 回 值:    新命令长度
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned char  Data_FormatChange(unsigned char Mode,unsigned char *PDin)
{
	unsigned char  length,BCC,i;
	unsigned char  Data[MAX_SER_SIZE];
	unsigned int   SUM=0;
	
	if(Mode == OLD_TO_NEW){
		memcpy(Data,PDin,PDin[FRAMELEN]);              //先将原始数据保存到Data中
		
		length = PDin[LENGTH]+NewFormatAddlength;
		
		PDin[Addr]	    = LocallAddr;
		PDin[Slot]		= SlotIndex;
		PDin[MSGseq]   = SMCSeq;
		PDin[MSGClass] = Data[CMDTYPE];
		
		PDin[MSG]	    = Data[COMMAND];
		PDin[MSG+1]    = 0x00;
		
		PDin[MSGLength]= Data[LENGTH];
		PDin[MSGLength+1]= 0x00;
		for(i=0;i<Data[LENGTH];i++)	//将数据信息拷贝
			PDin[MSGData+i]=Data[DATA+i] ;
		
		SUM = BCC_NEW(PDin,length-2);    //计算校验和
		
		PDin[length-2] = SUM&0xFF;            //取低字节
		PDin[length-1]   = SUM>>8;              //取高字节
	}else{
		length = PDin[MSGLength] + 10;           //计算出新帧总长度
		memcpy(Data,PDin,length);              //先将原始数据保存到Data中
		memset(PDin,0,MAX_SER_SIZE);
		PDin[FRAMELEN] = Data[MSGLength]+ PRTCLEN;  //计算出旧帧长度
		PDin[CMDTYPE]  = Data[MSGClass];
		PDin[STATUS]   = Data[4]+PDin[5];
		PDin[LENGTH]   = Data[MSGLength];
		// memcpy(PDin+4,&Data[MSGData],Data[MSGLength]);
		for(i=0;i<Data[MSGLength];i++)
			PDin[DATA+i] = Data[MSGData+i];
		BCC = 0;
		for(i=0; i<(PDin[FRAMELEN]-2); i++)
			BCC ^= PDin[i];
		PDin[PDin[FRAMELEN]-2] = ~BCC;
		PDin[PDin[FRAMELEN]-1] = ETX;	
		
	}
	
	return length;
}
//////////////////////////
// 函数原型:    unsigned int BCC_NEW(unsigned char *p,unsigned char length)
// 函数功能:    计算命令的累加和并取反输出
// 输入参数:    -		
// 输出参数:    无			// 模块信息
// 返 回 值:    检验和
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int BCC_NEW(const unsigned char *p, unsigned char length)
{
	unsigned int   BCC = 0x000; 	          //最大可到65535
    unsigned char   i = 0;	
	for (i = 0; i < length; i++) { 
		BCC += p[i]; 
	}
	return (~BCC) ;
}
//**************************************************************//
//                 ZLG600控制函数库                             //
//**************************************************************//

/*#if GET_DVC_INFO_EN


#if PCD_CONFIG_EN
unsigned char PCDConfig()
{
	unsigned char Status;
	
	SerBfr[CMDTYPE] = 1;
	SerBfr[COMMAND] = 'B';
	SerBfr[LENGTH] = 0;
	
	Status = ZLG522S_Cmd();
	
	if(Status == OK)
	{
		Status = SerBfr[STATUS];
	}
	return Status;
}
#endif
#if PCD_CLOSE_EN
unsigned char PCDClose()
{
	unsigned char Status;
	
	SerBfr[CMDTYPE] = 1;
	SerBfr[COMMAND] = 'C';
	SerBfr[LENGTH] = 0;
	
	Status = ZLG522S_Cmd();
	
	if(Status == OK)
	{
		Status = SerBfr[STATUS];
	}
	return Status;
}
#endif



#if PCDWriteReg_en
unsigned char PCDWriteReg(unsigned char RegAddr,unsigned char RegValue)
{
	unsigned char Status;
	
	SerBfr[CMDTYPE] = 1;
	SerBfr[COMMAND] = 'F';
	SerBfr[LENGTH] = 2;
	SerBfr[DATA] = RegAddr;
	SerBfr[DATA+1] = RegValue;
	
	Status = ZLG522S_Cmd();
	
	if(Status == OK)
	{
		Status = SerBfr[STATUS];
	}
	return Status;
}
#endif

#if PCDReadReg_en
unsigned char PCDReadReg(unsigned char RegAddr,unsigned char *RegValue)
{
	unsigned char Status;
	
	SerBfr[CMDTYPE] = 1;
	SerBfr[COMMAND] = 'G';
	SerBfr[LENGTH] = 1;
	SerBfr[DATA] = RegAddr;
	
	Status = ZLG522S_Cmd();
	
	if(Status == OK)
	{
		Status = SerBfr[STATUS];
		if(Status == OK)
			*RegValue = SerBfr[DATA];
	}
	return Status;
}
#endif

#if PICC_REQUEST_EN
unsigned char PiccRequest(unsigned char Req_Code,unsigned char *TagType)
{
	unsigned char Status;
	
	SerBfr[CMDTYPE] = 2;
	SerBfr[COMMAND] = 'A';
	SerBfr[LENGTH] = 1;
	SerBfr[DATA] = Req_Code;
	
	Status = ZLG522S_Cmd();
	
	if(Status == OK)
	{
		Status = SerBfr[STATUS];
		if(Status == OK)
		{
			*TagType = SerBfr[DATA];
			*(TagType+1) = SerBfr[DATA+1];
		}
	}
	return Status;
}
#endif

#if PiccAnticoll_en
unsigned char PiccAnticoll(unsigned char Sel_Code,unsigned char Bcnt,unsigned char *PiccSnr)
{
	unsigned char Status;
	
	SerBfr[CMDTYPE] = 2;
	SerBfr[COMMAND] = 'B';
	SerBfr[LENGTH] = 2;
	SerBfr[DATA] = Sel_Code;
	SerBfr[DATA+1] = Bcnt;
	
	Status = ZLG522S_Cmd();
	
	if(Status == OK)
	{
		Status = SerBfr[STATUS];
		if(Status == OK)
		{
			memcpy(PiccSnr,&SerBfr[DATA],4);
		}
	}
	return Status;
}
#endif

#if PiccSelect_en
unsigned char PiccSelect(unsigned char Sel_Code,unsigned char *PiccSnr,unsigned char *Sak)
{
	unsigned char Status;
	
	SerBfr[CMDTYPE] = 2;
	SerBfr[COMMAND] = 'C';
	SerBfr[LENGTH] = 5;
	SerBfr[DATA] = Sel_Code;
	memcpy(&SerBfr[DATA+1],PiccSnr,4);
	
	Status = ZLG522S_Cmd();
	
	if(Status == OK)
	{
		Status = SerBfr[STATUS];
		if(Status == OK)
		{
			*Sak = SerBfr[DATA];
		}
	}
	return Status;
}
#endif




#if PiccAutoDetect_en
unsigned char PiccAutoDetect(unsigned char OutMode,  unsigned char TxMode, unsigned char Req_Code, 
					 unsigned char AuthMode, unsigned char KEYAB,  unsigned char *Key, unsigned char Block)
{
	unsigned char Status;
	
	SerBfr[CMDTYPE] = 2;
	SerBfr[COMMAND] = 'N';

	if(AuthMode == 0)
		SerBfr[LENGTH] = 4;
	else
	{	SerBfr[DATA+4] = KEYAB;
		if(AuthMode == 'E')
		{
			SerBfr[DATA+5] = *Key;
			SerBfr[DATA+6] = Block;
			SerBfr[LENGTH] = 7;
		}
		else if(AuthMode == 'F')
		{
			memcpy(&SerBfr[DATA+5],Key,6);
			SerBfr[DATA+11] = Block;
			SerBfr[LENGTH] = 12;
		}
		else
			return COMMERR;
	}

	SerBfr[DATA] = OutMode;
	SerBfr[DATA+1] = TxMode;
	SerBfr[DATA+2] = Req_Code;
	SerBfr[DATA+3] = AuthMode;
	
	Status = ZLG522S_Cmd();
	
	if(Status == OK)
	{
		Status = SerBfr[STATUS];
	}
	return Status;
}
#endif

#if PiccADRcv_en
unsigned char PiccADRcv(unsigned char *TxDrv,unsigned char *TagType,unsigned char *Sak,unsigned char *Snr,unsigned char *DTBfr)
{
	unsigned char Status = 0xff;

	if(Ser_Rcv())
	{	
		if(SEQ == (SerBfr[CMDTYPE]&0xf0))
		{				//°üo??￥??
			Status = OK;
		}
		else
			Status = SEQERR;	//°üo?2??￥??

		if(Status == OK)
		{
			Status = SerBfr[STATUS];
			if(Status == OK)
			{
				*TxDrv = SerBfr[DATA];
				TagType[0] = SerBfr[DATA+1];
				TagType[1] = SerBfr[DATA+2];
				*Sak = SerBfr[DATA+3];
				memcpy(Snr,&SerBfr[DATA+5],SerBfr[DATA+4]);
				if(DTBfr != 0)
					memcpy(DTBfr,&SerBfr[DATA+5+SerBfr[DATA+4]],16);
			}
		}
	}
	return Status;
}
#endif

#if PiccReadADDT_en
unsigned char PiccReadADDT(unsigned char Mode,unsigned char *TxDrv,unsigned char *TagType,unsigned char *Sak,unsigned char *Snr,unsigned char *DTBfr)	//è?DTBfr?a??,?ò±íê?2??áéè??êy?Y
{
	unsigned char Status;

	SerBfr[CMDTYPE] = 2;
	SerBfr[COMMAND] = 'O';
	SerBfr[LENGTH] = 1;
	SerBfr[DATA] = Mode;
	
	Status = ZLG522S_Cmd();

	if(Status == OK)
	{
		Status = SerBfr[STATUS];
		if(Status == OK)
		{
			*TxDrv = SerBfr[DATA];
			TagType[0] = SerBfr[DATA+1];
			TagType[1] = SerBfr[DATA+2];
			*Sak = SerBfr[DATA+3];
			memcpy(Snr,&SerBfr[DATA+5],SerBfr[DATA+4]);
			if(DTBfr != 0)
				memcpy(DTBfr,&SerBfr[DATA+5+SerBfr[DATA+4]],16);
		}
	}

	return Status;
}*/

