#include "MF522.h"
#include "HW_MCUIO.h"//#include "stm32f4xx_hal.h"
#include "platform.h"
#include "platform_interface.h"
#include "function.h"


#if (NFC==1) //#if defined(NFC)&&(NFC==1)
/*
2020.03,由于和Ethernet共用spi，Ethernet对速度要求高，所以切换到系统spi3
2020.05,修改硬件V03板，和W5500完全独立出来; RC522用模拟spi。
*/
//#ifdef 		STM32F405xx	//为F401增加
#define 	SYS_SPI3
extern 		SPI_HandleTypeDef hspi3;
//#endif


#define 	MF_DELAY		2//3//5
#define 	MAXRLEN 		18


/*
This i2c driver from stm32F1xx; we should add delay when operation io, 
because the stm32F4 much fast (The main frequency of stm32F4xx is 168M) !!
F4系列速度太快，需要加延时，读写才正常!!!*/
static void mDelay(unsigned int nCount)
{
    for (; nCount != 0; nCount--);
}



	#define 	MF522_RST_PORT	GPIOA
	#define 	MF522_RST_PIN		GPIO_PIN_15	
	#define 	MF522_CS_PORT		GPIOE
	#define 	MF522_CS_PIN		GPIO_PIN_6	
	
#define SET_MF522_RST   {HAL_GPIO_WritePin(MF522_RST_PORT,MF522_RST_PIN,GPIO_PIN_SET);mDelay(MF_DELAY);}
#define RESET_MF522_RST {HAL_GPIO_WritePin(MF522_RST_PORT,MF522_RST_PIN,GPIO_PIN_RESET);mDelay(MF_DELAY);}
#define SET_MF522_NS  	{HAL_GPIO_WritePin(MF522_CS_PORT,MF522_CS_PIN,GPIO_PIN_SET);mDelay(MF_DELAY);}
#define RESET_MF522_NS  {HAL_GPIO_WritePin(MF522_CS_PORT,MF522_CS_PIN,GPIO_PIN_RESET);mDelay(MF_DELAY);}

//#ifndef SYS_SPI3		
	#define 	MF522_SCK_PORT	GPIOC
	#define 	MF522_SCK_PIN		GPIO_PIN_15//GPIO_PIN_10			
	#define 	MF522_SI_PORT		GPIOC
	#define 	MF522_SI_PIN		GPIO_PIN_14//GPIO_PIN_12		
	#define 	MF522_MI_PORT		GPIOE//GPIOC
	#define 	MF522_MI_PIN		GPIO_PIN_12//GPIO_PIN_11	

#define SET_MF522_SCK   {HAL_GPIO_WritePin(MF522_SCK_PORT,MF522_SCK_PIN,GPIO_PIN_SET);mDelay(MF_DELAY);}
#define RESET_MF522_SCK {HAL_GPIO_WritePin(MF522_SCK_PORT,MF522_SCK_PIN,GPIO_PIN_RESET);mDelay(MF_DELAY);}

#define SET_MF522_SI		{HAL_GPIO_WritePin(MF522_SI_PORT,MF522_SI_PIN,GPIO_PIN_SET);mDelay(MF_DELAY);}
#define RESET_MF522_SI  {HAL_GPIO_WritePin(MF522_SI_PORT,MF522_SI_PIN,GPIO_PIN_RESET);mDelay(MF_DELAY);}

#define READ_MISO				HAL_GPIO_ReadPin(MF522_MI_PORT,MF522_MI_PIN);
//#endif





//-----------------------------------------------------------------
static void SPI_InitIO(void)
{

		GPIO_InitTypeDef GPIO_InitStruct = {0};

	
		GPIO_InitStruct.Pin = MF522_RST_PIN;
		GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
		GPIO_InitStruct.Pull = GPIO_NOPULL;
		GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;//GPIO_SPEED_FREQ_HIGH;
		HAL_GPIO_Init(MF522_RST_PORT, &GPIO_InitStruct);
	 
		GPIO_InitStruct.Pin = MF522_CS_PIN;
		GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
		GPIO_InitStruct.Pull = GPIO_NOPULL;
		GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH ;//GPIO_SPEED_FREQ_HIGH;//GPIO_SPEED_FREQ_MEDIUM;//
		HAL_GPIO_Init(MF522_CS_PORT, &GPIO_InitStruct); 


if( !get_hard_flag()){	
//#ifndef SYS_SPI3		
		GPIO_InitStruct.Pin = MF522_SCK_PIN;
		GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
		GPIO_InitStruct.Pull = GPIO_NOPULL;
		GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
		HAL_GPIO_Init(MF522_SCK_PORT, &GPIO_InitStruct);
	 
		GPIO_InitStruct.Pin = MF522_SI_PIN;
		GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
		GPIO_InitStruct.Pull = GPIO_NOPULL;
		GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
		HAL_GPIO_Init(MF522_SI_PORT, &GPIO_InitStruct); 		
		
		//MISO
		GPIO_InitStruct.Pin = MF522_MI_PIN;
		GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
		GPIO_InitStruct.Pull = GPIO_PULLUP;//
		GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
		HAL_GPIO_Init(MF522_MI_PORT, &GPIO_InitStruct);
}

	  SET_MF522_RST    //*MF522_RST=1;
    SET_MF522_NS //*MF522_NS =1;
//#endif 


}




/////////////////////////////////////////////////////////////////////
//功    能：写RC632寄存器
//参数说明：Address[IN]:寄存器地址
//          value[IN]:写入的值
/////////////////////////////////////////////////////////////////////
static void WriteRawRC(unsigned char Address, unsigned char value)
{
	//#ifdef SYS_SPI3
	if( get_hard_flag() ){
    unsigned char ucAddr= ((Address << 1) & 0x7E);
		unsigned char tmp[2];
		tmp[0] =ucAddr;
		tmp[1] =value;	
		RESET_MF522_NS //*MF522_NS = 0;
		HAL_SPI_Transmit(&hspi3,tmp,2,100);	
		SET_MF522_NS      //*MF522_NS = 1;	
	//#else	
	}
	else{
    unsigned char i, ucAddr;

    RESET_MF522_SCK    //*MF522_SCK = 0;
		RESET_MF522_NS //*MF522_NS = 0;
		ucAddr = ((Address << 1) & 0x7E);

    for (i = 8; i > 0; i--){
        if ((ucAddr & 0x80) == 0x80)
            SET_MF522_SI
        else
            RESET_MF522_SI

        SET_MF522_SCK //*MF522_SCK = 1;
        ucAddr <<= 1;
        RESET_MF522_SCK //*MF522_SCK = 0;
    }

    for (i = 8; i > 0; i--){
        if ((value & 0x80) == 0x80)
            SET_MF522_SI
        else
            RESET_MF522_SI

        SET_MF522_SCK //*MF522_SCK = 1;
        value <<= 1;
        RESET_MF522_SCK //*MF522_SCK = 0;
    }

    SET_MF522_NS      //*MF522_NS = 1;
    SET_MF522_SCK //*MF522_SCK = 1;
	}
//#endif		
		
}

/////////////////////////////////////////////////////////////////////
//功    能：读RC632寄存器
//参数说明：Address[IN]:寄存器地址
//返    回：读出的值
/////////////////////////////////////////////////////////////////////
static unsigned char ReadRawRC(unsigned char Address)
{
	//#ifdef SYS_SPI3
	if( get_hard_flag()){
    unsigned char value[2],ucAddr = ((Address << 1) & 0x7E) | 0x80; 
	
		RESET_MF522_NS //*MF522_NS = 0;
		HAL_SPI_TransmitReceive(&hspi3,&ucAddr,value,2,100);
		SET_MF522_NS      //*MF522_NS = 1;
	
		return value[1];
	//#else
	}
	else{
    unsigned char i, ucAddr, ucResult = 0;

    RESET_MF522_SCK; //*MF522_SCK = 0;
    RESET_MF522_NS;  //*MF522_NS = 0;

    ucAddr = ((Address << 1) & 0x7E) | 0x80;

    for (i = 8; i > 0; i--){
        if ((ucAddr & 0x80) == 0x80)
            SET_MF522_SI
        else
            RESET_MF522_SI

        SET_MF522_SCK //*MF522_SCK = 1;
        ucAddr <<= 1;
        RESET_MF522_SCK //*MF522_SCK = 0;
    }

    for (i = 8; i > 0; i--){
        SET_MF522_SCK //*MF522_SCK = 1;
        ucResult <<= 1;
				ucResult |=HAL_GPIO_ReadPin(MF522_MI_PORT,MF522_MI_PIN);
        RESET_MF522_SCK //*MF522_SCK = 0;
    }

    SET_MF522_NS;  //*MF522_NS = 1;
    SET_MF522_SCK; //*MF522_SCK = 1;
    return ucResult;
	}
	//#endif
}

/////////////////////////////////////////////////////////////////////
//功    能：置RC522寄存器位
//参数说明：reg[IN]:寄存器地址
//          mask[IN]:置位值
/////////////////////////////////////////////////////////////////////
static void SetBitMask(unsigned char reg, unsigned char mask)
{
    char tmp = 0x0;
    tmp = ReadRawRC(reg);
    WriteRawRC(reg, tmp | mask); // set bit mask
}

/////////////////////////////////////////////////////////////////////
//功    能：清RC522寄存器位
//参数说明：reg[IN]:寄存器地址
//          mask[IN]:清位值
/////////////////////////////////////////////////////////////////////
static void ClearBitMask(unsigned char reg, unsigned char mask)
{
    char tmp = 0x0;
    tmp = ReadRawRC(reg);
    WriteRawRC(reg, tmp & ~mask); // clear bit mask
}

/////////////////////////////////////////////////////////////////////
//用MF522计算CRC16函数
/////////////////////////////////////////////////////////////////////
static void CalulateCRC(unsigned char *pIndata, unsigned char len, unsigned char *pOutData)
{
    unsigned char i, n;
    ClearBitMask(DivIrqReg, 0x04);
    WriteRawRC(CommandReg, PCD_IDLE);
    SetBitMask(FIFOLevelReg, 0x80);
    for (i = 0; i < len; i++)
    {
        WriteRawRC(FIFODataReg, *(pIndata + i));
    }
    WriteRawRC(CommandReg, PCD_CALCCRC);
		
    i = 0xFF;	
    do
    {
        n = ReadRawRC(DivIrqReg);
        i--;
    } while ((i != 0) && !(n & 0x04));
    pOutData[0] = ReadRawRC(CRCResultRegL);
    pOutData[1] = ReadRawRC(CRCResultRegM);
}

/////////////////////////////////////////////////////////////////////
//开启天线
//每次启动或关闭天险发射之间应至少有1ms的间隔
/////////////////////////////////////////////////////////////////////
static void PcdAntennaOn(void)
{
    unsigned char i;
    i = ReadRawRC(TxControlReg);

    if (!(i & 0x03))
    {
        SetBitMask(TxControlReg, 0x03);
    }
}

/////////////////////////////////////////////////////////////////////
//关闭天线
/////////////////////////////////////////////////////////////////////
static void PcdAntennaOff(void)
{
    ClearBitMask(TxControlReg, 0x03);
}


//----------------------------------------
static char PcdReset(void)
{
//    SET_MF522_RST      //*MF522_RST=1;
//		mDelay(50000); 
    RESET_MF522_RST    //*MF522_RST=0;
    mDelay(50000); 
    SET_MF522_RST      //*MF522_RST=1;
    mDelay(50000); 
    WriteRawRC(CommandReg, PCD_RESETPHASE);

    mDelay(500); //_nop_();

    WriteRawRC(ModeReg, 0x3D); //和Mifare卡通讯，CRC初始值0x6363
    WriteRawRC(TReloadRegL, 30);
    WriteRawRC(TReloadRegH, 0);
    WriteRawRC(TModeReg, 0x8D);
    WriteRawRC(TPrescalerReg, 0x3E);

    WriteRawRC(TxAutoReg, 0x40); //必须要   ，设置逻辑1，强制100%ASK调制 	  Gavin

    return MI_OK;
}

/////////////////////////////////////////////////////////////////////
//功    能：通过RC522和ISO14443卡通讯
//参数说明：Command[IN]:RC522命令字
//          pInData[IN]:通过RC522发送到卡片的数据
//          InLenByte[IN]:发送数据的字节长度
//          pOutData[OUT]:接收到的卡片返回数据
//          *pOutLenBit[OUT]:返回数据的位长度
/////////////////////////////////////////////////////////////////////
//char PcdComMF522(unsigned char Command,
static int PcdComMF522(unsigned char Command,
                       unsigned char *pInData,
                       unsigned char InLenByte,
                       unsigned char *pOutData,
                       unsigned int *pOutLenBit)
{
    //char status = MI_ERR;
    int status = MI_ERR;

    unsigned char irqEn = 0x00;
    unsigned char waitFor = 0x00; //Mask by Gavin
    unsigned char lastBits;
    unsigned char n;
    unsigned int i;

    switch (Command)
    {
    case PCD_AUTHENT:
        irqEn = 0x12;
        waitFor = 0x10;
        break;
    case PCD_TRANSCEIVE:
        irqEn = 0x77;
        waitFor = 0x30; //Mask by Gavin
        break;
    default:
        break;
    }

    WriteRawRC(ComIEnReg, irqEn | 0x80); //reg0x02
    ClearBitMask(ComIrqReg, 0x80);       //reg0x04   ==0
    WriteRawRC(CommandReg, PCD_IDLE);    //reg0x01
    SetBitMask(FIFOLevelReg, 0x80);      //reg0x0A

    for (i = 0; i < InLenByte; i++)
    {
        WriteRawRC(FIFODataReg, pInData[i]);
    } //reg0x09
    WriteRawRC(CommandReg, Command);

    if (Command == PCD_TRANSCEIVE)
    {
        SetBitMask(BitFramingReg, 0x80);
    } //reg0x0D

    //      i = 600;//根据时钟频率调整，操作M1卡最大等待时间25ms
    i = 3600;
		#ifdef	_NEW_NFC_APP
    i=1000;//800;		//420是临界值
		#endif
    do
    {
        n = ReadRawRC(ComIrqReg); //reg0x04
        i--;
    } while ((i != 0) && !(n & 0x01) && !(n & waitFor));
		
		

    ClearBitMask(BitFramingReg, 0x80);

    if (i != 0)
    {
        if (!(ReadRawRC(ErrorReg) & 0x1B))
        {
            status = MI_OK;
            if (n & irqEn & 0x01) //timer IrQ==1 设定时间里没有找到？
            {
                status = MI_NOTAGERR;
            }

            if (Command == PCD_TRANSCEIVE)
            {
                n = ReadRawRC(FIFOLevelReg);
                lastBits = ReadRawRC(ControlReg) & 0x07;
                if (lastBits)
                {
                    *pOutLenBit = (n - 1) * 8 + lastBits;
                }
                else
                {
                    *pOutLenBit = n * 8;
                }
                if (n == 0)
                {
                    n = 1;
                }
                if (n > MAXRLEN)
                {
                    n = MAXRLEN;
                }
                for (i = 0; i < n; i++)
                {
                    pOutData[i] = ReadRawRC(FIFODataReg);
                }
            }
        }
        else
        {
            status = MI_ERR;
        }
    }

    SetBitMask(ControlReg, 0x80); // stop timer now
    WriteRawRC(CommandReg, PCD_IDLE);
    return status;
}

/////////////////////////////////////////////////////////////////////
//功    能：寻卡
//参数说明: req_code[IN]:寻卡方式
//                0x52 = 寻感应区内所有符合14443A标准的卡
//                0x26 = 寻未进入休眠状态的卡
//          pTagType[OUT]：卡片类型代码
//                0x4400 = Mifare_UltraLight
//                0x0400 = Mifare_One(S50)
//                0x0200 = Mifare_One(S70)
//                0x0800 = Mifare_Pro(X)
//                0x4403 = Mifare_DESFire
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
//char PcdRequest(unsigned char req_code,unsigned char *pTagType)
#ifdef _NEW_NFC_APP
/* 2020.12.04 Gavin He
* 调试发现，扫描函数PcdRequest 会消耗至少3ms的时间，这样拖慢整个主循环;
* 慢的原因: 调用的PcdComMF522函数中有死循环等待！
* 解决办法：将函数拆分成多个状态机，在主循环里多次访问完成;
*/
static int PcdRequest(unsigned char req_code, unsigned char *pTagType)
{
		//PcdRequest 内部变量,
    int status = 1;//MI_ERR;
    static unsigned int unLen = 0;
    static unsigned char ucComMF522Buf[MAXRLEN];	
		//PcdComMF522 内部变量
    static unsigned char irqEn = 0x00;
    static unsigned char waitFor = 0x00; //Mask by Gavin
    unsigned char lastBits;
    static unsigned char n;
    static unsigned int i;
		/*static int PcdComMF522(unsigned char Command,
													 unsigned char *pInData,
													 unsigned char InLenByte,
													 unsigned char *pOutData,
													 unsigned int *pOutLenBit)*/
		//PcdComMF522 function input
		static unsigned char Command;
		static unsigned char *pInData;
		static unsigned char InLenByte;
		static unsigned char *pOutData;
		static unsigned int *pOutLenBit;		
		
		static unsigned char find_step=0;	//add by Gavin		
	
		switch(find_step){
			
			case 0:			
			//----- PcdRequest part 1 ---------------------
				ClearBitMask(Status2Reg, 0x08);
				WriteRawRC(BitFramingReg, 0x07);
				SetBitMask(TxControlReg, 0x03);
				ucComMF522Buf[0] = req_code;
			
			//------- call function: PcdComMF522 Part1 start ----------
				//status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 1, ucComMF522Buf, &unLen);
					Command = PCD_TRANSCEIVE;
					pInData = ucComMF522Buf;
					InLenByte =1;
					pOutData = ucComMF522Buf;
					unLen = 0;
					pOutLenBit =&unLen;
				
					switch (Command)
					{
					case PCD_AUTHENT:
							irqEn = 0x12;
							waitFor = 0x10;
							break;
					case PCD_TRANSCEIVE:
							irqEn = 0x77;
							waitFor = 0x30; //Mask by Gavin
							break;
					default:
							break;
					}

					WriteRawRC(ComIEnReg, irqEn | 0x80); //reg0x02
					ClearBitMask(ComIrqReg, 0x80);       //reg0x04   ==0
					WriteRawRC(CommandReg, PCD_IDLE);    //reg0x01
					SetBitMask(FIFOLevelReg, 0x80);      //reg0x0A

					for (i = 0; i < InLenByte; i++)
					{
							WriteRawRC(FIFODataReg, pInData[i]);
					} //reg0x09
					WriteRawRC(CommandReg, Command);

					if (Command == PCD_TRANSCEIVE)
					{
							SetBitMask(BitFramingReg, 0x80);
					} //reg0x0D
				//-------- call function: PcdComMF522 Part1 end ---------------------	
				
				i=200; //set waitfor timer
				find_step =1;	
				//break;
							
			case 1:
				//-------- call function: PcdComMF522 Part2  ---------------------	
				/*
				i = 3600;
				i=430;		//420是临界值
				do
				{
						n = ReadRawRC(ComIrqReg); //reg0x04
						i--;
				} while ((i != 0) && !(n & 0x01) && !(n & waitFor));
				*/
//			#define 	W_TIMER	255
				i--;		
				n = ReadRawRC(ComIrqReg); //reg0x04
				if ( (i != 0) &&!(n & 0x01) && !(n & waitFor)){
					//None find
					status = 1;
				}					
				else{
					//find;
					status = 1;
					find_step =2	;				
				}
				
				//--------------------------------------------------------------------------------
				break;	
			
			case 2:
				//-------- call function: PcdComMF522 Part3  ---------------------
				ClearBitMask(BitFramingReg, 0x80);

				if (i != 0) 
				{
						if (!(ReadRawRC(ErrorReg) & 0x1B))
						{
								status = MI_OK;
								if (n & irqEn & 0x01) //timer IrQ==1 设定时间里没有找到？
								{
										status = MI_NOTAGERR;
								}

								if (Command == PCD_TRANSCEIVE)
								{
										n = ReadRawRC(FIFOLevelReg);
										lastBits = ReadRawRC(ControlReg) & 0x07;
										if (lastBits)
										{
												*pOutLenBit = (n - 1) * 8 + lastBits;
										}
										else
										{
												*pOutLenBit = n * 8;
										}
										if (n == 0)
										{
												n = 1;
										}
										if (n > MAXRLEN)
										{
												n = MAXRLEN;
										}
										for (i = 0; i < n; i++)
										{
												pOutData[i] = ReadRawRC(FIFODataReg);
										}
								}
						}
						else
						{
								status = MI_ERR;
						}
				}
				SetBitMask(ControlReg, 0x80); // stop timer now
				WriteRawRC(CommandReg, PCD_IDLE);	
				//-------- call function: PcdComMF522 Part3  end ---------------------
				
				//----- PcdRequest part 2 ---------------------
				if ((status == MI_OK) && (unLen == 0x10))
				{
						*pTagType = ucComMF522Buf[0];
						*(pTagType + 1) = ucComMF522Buf[1];
				}
				else
				{
						status = MI_ERR;
				}

				find_step =0;			
				break;			
			
			default:
				status = MI_ERR;
				break;
		}//sw
		
    return status;
}

#else
static int PcdRequest(unsigned char req_code, unsigned char *pTagType)
{
    int status; //
    //char status;
    unsigned int unLen = 0;
    unsigned char ucComMF522Buf[MAXRLEN];

    ClearBitMask(Status2Reg, 0x08);
    WriteRawRC(BitFramingReg, 0x07);
    SetBitMask(TxControlReg, 0x03);

    ucComMF522Buf[0] = req_code;

    status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 1, ucComMF522Buf, &unLen);

    if ((status == MI_OK) && (unLen == 0x10))
    {
        *pTagType = ucComMF522Buf[0];
        *(pTagType + 1) = ucComMF522Buf[1];
    }
    else
    {
        status = MI_ERR;
    }

    return status;
}
#endif 



#if 0
/////////////////////////////////////////////////////////////////////
//功    能：防冲撞
//参数说明: pSnr[OUT]:卡片序列号，4字节
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////  
//char PcdAnticoll(unsigned char *pSnr)
static int PcdAnticoll(unsigned char *pSnr)
{
    //char status;
	int status;
    unsigned char i,snr_check=0;
    unsigned int  unLen;
    unsigned char ucComMF522Buf[MAXRLEN]; 
    

    ClearBitMask(Status2Reg,0x08);
    WriteRawRC(BitFramingReg,0x00);
    ClearBitMask(CollReg,0x80);
 
    ucComMF522Buf[0] = PICC_ANTICOLL1;
    ucComMF522Buf[1] = 0x20;

    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen);

    if (status == MI_OK)
    {
    	 for (i=0; i<4; i++)
         {   
             *(pSnr+i)  = ucComMF522Buf[i];
             snr_check ^= ucComMF522Buf[i];
         }
         if (snr_check != ucComMF522Buf[i])
         {   status = MI_ERR;    }
    }
    
    SetBitMask(CollReg,0x80);
    return status;
}


/////////////////////////////////////////////////////////////////////
//功    能：选定卡片
//参数说明: pSnr[IN]:卡片序列号，4字节
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
static int PcdSelect(unsigned char *pSnr)
{
    int status;
    unsigned char i;
    unsigned int  unLen;
    unsigned char ucComMF522Buf[MAXRLEN]; 
    
    ucComMF522Buf[0] = PICC_ANTICOLL1;
    ucComMF522Buf[1] = 0x70;
    ucComMF522Buf[6] = 0;
    for (i=0; i<4; i++)
    {
    	ucComMF522Buf[i+2] = *(pSnr+i);
    	ucComMF522Buf[6]  ^= *(pSnr+i);
    }
    CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf[7]);
  
    ClearBitMask(Status2Reg,0x08);

    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen);
    
    if ((status == MI_OK) && (unLen == 0x18))
    {   status = MI_OK;  }
    else
    {   status = MI_ERR;    }

    return status;
}
#else //将防碰撞级别由内置改为作为形参出入。YSY 2019.10.14
/////////////////////////////////////////////////////////////////////
//功    能：防冲撞
//参数说明: pSnr[OUT]:卡片序列号，4字节
//         sec_code[IN]：防碰撞级别
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
//char PcdAnticoll(unsigned char *pSnr)
static int PcdAnticoll(unsigned char sec_code, unsigned char *pSnr)
{
    //char status;
    int status;
    unsigned char i, snr_check = 0;
    unsigned int unLen;
    unsigned char ucComMF522Buf[MAXRLEN];

    ClearBitMask(Status2Reg, 0x08);
    WriteRawRC(BitFramingReg, 0x00);
    ClearBitMask(CollReg, 0x80);

    ucComMF522Buf[0] = sec_code;
    ucComMF522Buf[1] = 0x20;

    status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 2, ucComMF522Buf, &unLen);

    if (status == MI_OK)
    {
        for (i = 0; i < 4; i++)
        {
            *(pSnr + i) = ucComMF522Buf[i];
            snr_check ^= ucComMF522Buf[i];
        }
        if (snr_check != ucComMF522Buf[i])
        {
            status = MI_ERR;
        }
    }

    SetBitMask(CollReg, 0x80);
    return status;
}

/////////////////////////////////////////////////////////////////////
//功    能：选定卡片
//参数说明: pSnr[IN]:卡片序列号，4字节
//         sec_code[IN]：防碰撞级别
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
static int PcdSelect(unsigned char sec_code, unsigned char *pSnr)
{
    int status;
    unsigned char i;
    unsigned int unLen;
    unsigned char ucComMF522Buf[MAXRLEN];

    ucComMF522Buf[0] = sec_code;
    ucComMF522Buf[1] = 0x70;
    ucComMF522Buf[6] = 0;
    for (i = 0; i < 4; i++)
    {
        ucComMF522Buf[i + 2] = *(pSnr + i);
        ucComMF522Buf[6] ^= *(pSnr + i);
    }
    CalulateCRC(ucComMF522Buf, 7, &ucComMF522Buf[7]);

    ClearBitMask(Status2Reg, 0x08);

    status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 9, ucComMF522Buf, &unLen);

    if ((status == MI_OK) && (unLen == 0x18))
    {
        status = MI_OK;
    }
    else
    {
        status = MI_ERR;
    }

    return status;
}
#endif



/////////////////////////////////////////////////////////////////////
//功    能：验证卡片密码
//参数说明: auth_mode[IN]: 密码验证模式
//                 0x60 = 验证A密钥
//                 0x61 = 验证B密钥
//          addr[IN]：块地址
//          pKey[IN]：密码
//          pSnr[IN]：卡片序列号，4字节
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
//static int PcdAuthState(unsigned char auth_mode, unsigned char addr, unsigned char *pKey, unsigned char *pSnr)
//{
//    int status;
//    unsigned int unLen;
//    unsigned char i, ucComMF522Buf[MAXRLEN];

//    ucComMF522Buf[0] = auth_mode;
//    ucComMF522Buf[1] = addr;
//    for (i = 0; i < 6; i++)
//    {
//        ucComMF522Buf[i + 2] = *(pKey + i);
//    }
//    for (i=0; i<6; i++)
//    //for (i = 0; i < 4; i++)
//    {
//        ucComMF522Buf[i + 8] = *(pSnr + i);
//    }
//    //   memcpy(&ucComMF522Buf[2], pKey, 6);
//    //   memcpy(&ucComMF522Buf[8], pSnr, 4);

//    status = PcdComMF522(PCD_AUTHENT, ucComMF522Buf, 12, ucComMF522Buf, &unLen);
//    if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08)))
//    {
//        status = MI_ERR;
//    }

//    return status;
//}


/////////////////////////////////////////////////////////////////////
//功    能：写数据到M1卡一块
//参数说明: addr[IN]：块地址
//          pData[IN]：写入的数据，16字节
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
static int PcdWrite(unsigned char addr, unsigned char *pData)
{
    int status;
    unsigned int unLen;
    unsigned char i, ucComMF522Buf[MAXRLEN];

    ucComMF522Buf[0] = PICC_WRITE;
    ucComMF522Buf[1] = addr;
    CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);

    status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, &unLen);

    if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
    {
        status = MI_ERR;
    }
		
    if (status == MI_OK)
    {
        //memcpy(ucComMF522Buf, pData, 16);
        //for (i = 0; i < 4; i++)
			  for (i = 0; i < 16; i++)
        {
            ucComMF522Buf[i] = *(pData + i);
        }
        CalulateCRC(ucComMF522Buf, 16, &ucComMF522Buf[16]);

        status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 18, ucComMF522Buf, &unLen);
        if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
        {
            status = MI_ERR;
        }
    }

    return status;
}

/////////////////////////////////////////////////////////////////////
//功    能：读取M1卡一块数据
//参数说明: addr[IN]：块地址
//          pData[OUT]：读出的数据，16字节
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
static int PcdRead(unsigned char addr, unsigned char *pData)
{
    int status;
    unsigned int unLen;
    unsigned char i, ucComMF522Buf[MAXRLEN];

    ucComMF522Buf[0] = PICC_READ;
    ucComMF522Buf[1] = addr;
    CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);

    status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, &unLen);
    //if (status == MI_OK)
        if ((status == MI_OK) && (unLen == 0x90))
     //  {   memcpy(pData, ucComMF522Buf, 16);   }
    {
        //for (i = 0; i < 4; i++)//
				for (i = 0; i < 16; i++)	//2020.02.17 Gavin modify			
        {
            *(pData + i) = ucComMF522Buf[i];
        }
    }
    else
    {
        status = MI_ERR;
    }

    return status;
}

#ifdef NOUSE

/////////////////////////////////////////////////////////////////////
//功    能：扣款和充值
//参数说明: dd_mode[IN]：命令字
//               0xC0 = 扣款
//               0xC1 = 充值
//          addr[IN]：钱包地址
//          pValue[IN]：4字节增(减)值，低位在前
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
static int PcdValue(unsigned char dd_mode, unsigned char addr, unsigned char *pValue)
{
    int status;
    unsigned int unLen;
    unsigned char i, ucComMF522Buf[MAXRLEN];

    ucComMF522Buf[0] = dd_mode;
    ucComMF522Buf[1] = addr;
    CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);

    status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, &unLen);

    if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
    {
        status = MI_ERR;
    }

    if (status == MI_OK)
    {
        // memcpy(ucComMF522Buf, pValue, 4);
        for (i = 0; i < 16; i++)
        {
            ucComMF522Buf[i] = *(pValue + i);
        }
        CalulateCRC(ucComMF522Buf, 4, &ucComMF522Buf[4]);
        unLen = 0;
        status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 6, ucComMF522Buf, &unLen);
        if (status != MI_ERR)
        {
            status = MI_OK;
        }
    }

    if (status == MI_OK)
    {
        ucComMF522Buf[0] = PICC_TRANSFER;
        ucComMF522Buf[1] = addr;
        CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);

        status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, &unLen);

        if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
        {
            status = MI_ERR;
        }
    }
    return status;
}

/////////////////////////////////////////////////////////////////////
//功    能：备份钱包
//参数说明: sourceaddr[IN]：源地址
//          goaladdr[IN]：目标地址
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
static int PcdBakValue(unsigned char sourceaddr, unsigned char goaladdr)
{
    int status;
    unsigned int unLen;
    unsigned char ucComMF522Buf[MAXRLEN];

    ucComMF522Buf[0] = PICC_RESTORE;
    ucComMF522Buf[1] = sourceaddr;
    CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);

    status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, &unLen);

    if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
    {
        status = MI_ERR;
    }

    if (status == MI_OK)
    {
        ucComMF522Buf[0] = 0;
        ucComMF522Buf[1] = 0;
        ucComMF522Buf[2] = 0;
        ucComMF522Buf[3] = 0;
        CalulateCRC(ucComMF522Buf, 4, &ucComMF522Buf[4]);

        status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 6, ucComMF522Buf, &unLen);
        if (status != MI_ERR)
        {
            status = MI_OK;
        }
    }

    if (status != MI_OK)
    {
        return MI_ERR;
    }

    ucComMF522Buf[0] = PICC_TRANSFER;
    ucComMF522Buf[1] = goaladdr;

    CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);

    status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, &unLen);

    if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
    {
        status = MI_ERR;
    }

    return status;
}

/////////////////////////////////////////////////////////////////////
//功    能：命令卡片进入休眠状态
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
static int PcdHalt(void)
{
    int status = 0x00;
    unsigned int unLen;
    unsigned char ucComMF522Buf[MAXRLEN];

    ucComMF522Buf[0] = PICC_HALT;
    ucComMF522Buf[1] = 0;
    CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);

    status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, &unLen);

    // return MI_OK;
    return status;
}
#endif




#define 	CARD_SN_LEN		8
unsigned char error_count=0;
unsigned char card_SN_last[CARD_SN_LEN];
#include "string.h"
//
////MF522	卡验证时需要参数
//unsigned char DefaultKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 
/*
s1，开启自动寻卡,等待直到有卡0xE6+ 1byte + 4byte的序列号
S2,关闭自动寻卡
S3,开启1444A复合寻卡
S4, 读写操作 */
#ifdef _NEW_NFC_APP

int nfc_write_read_N_block(struct nfc_app_STR *nfc)	
{
		unsigned char card_type[2];
		unsigned char card_SN[4]; 
		unsigned char card_SN_this[CARD_SN_LEN];
		unsigned char i,rtmp[16],tmp[16],status;	

   //寻卡，----得到卡的类型0x4400
    if(  (status =PcdRequest(PICC_REQALL, card_type) ) != MI_OK){		
			if( (status!=1) && (++error_count>=30) ){
				error_count=0;
				memset(card_SN_last,0,CARD_SN_LEN);
			}
			return 0xE0; //return MI_ERR;	
		}
		/* 	FM11NT 	---0x44 , 0x00
				M1			---0x04 ,					//白卡
		*/	

		//更改为M0卡的防冲撞流程 YSY 2019.10.14
    //防冲撞,----得到  卡片序列号，4字节
    if( PcdAnticoll(0x93, card_SN) != MI_OK)
        return 0xE1; //return MI_ERR;goto rfid_error1;
		memcpy(card_SN_this,card_SN,4);
    //选卡--INPUT 卡片的序列号4字节!!
    if(  PcdSelect(0x93, card_SN)!= MI_OK)
        return 0xE1; //goto rfid_error1;
    if(  PcdAnticoll(0x95, card_SN)!= MI_OK)
        return 0xE1; //goto rfid_error1;
		memcpy(card_SN_this+4,card_SN,4);	

		error_count =0;
		if(memcmp(card_SN_this,card_SN_last,CARD_SN_LEN) ==0)						
			return 1;	//tag保持add by Gavin 便于外部做应用		
		
    //选卡--INPUT 卡片的序列号4字节!!
    if(  PcdSelect(0x95, card_SN) != MI_OK)
        return 0xE1; //goto rfid_error1;
							
	
		//---------------------------------------------------------------------		
		//a,write 
		for(i=0;i<nfc->wblock_cnt;i++){
			//a1, read
			if(PcdRead(nfc->waddr[i],rtmp)!= MI_OK)
				goto rfid_error_retry1;				
			//a2,  modify
			memcpy(rtmp,nfc->wbuf[i],4);							
			//a3,write 
			if(PcdWrite(nfc->waddr[i], rtmp) != MI_OK)
				goto rfid_error_retry2;			
		}//for

		//a4,read then check them	
		for(i=0;i<nfc->wblock_cnt;i++){			
			if(PcdRead(nfc->waddr[i],tmp)!= MI_OK)
				goto rfid_error_retry3;
			if( memcmp(nfc->wbuf[i],tmp,4) !=0 )
				goto rfid_error_retry4;				
		}//for

		//20201016 add by Gavin 修改次数
		if(nfc->card_write_cnt_addr !=0){
			unsigned int r_count,w_count=0;
			if(PcdRead(nfc->card_write_cnt_addr,tmp)!= MI_OK)
				goto rfid_error_retry6;
			w_count =(tmp[0]<<24)+(tmp[1]<<16)+(tmp[2]<<8)+(tmp[3]<<0) +1;
			tmp[0] = w_count>>24;
			tmp[1] = w_count>>16;
			tmp[2] = w_count>>8;
			tmp[3] = w_count>>0;
			if(PcdWrite(nfc->card_write_cnt_addr, tmp) != MI_OK)
				goto rfid_error_retry6;	
			
			//read and check 
			if(PcdRead(nfc->card_write_cnt_addr,tmp)!= MI_OK)
				goto rfid_error_retry6;
			r_count =(tmp[0]<<24)+(tmp[1]<<16)+(tmp[2]<<8)+(tmp[3]<<0);
			if( w_count != r_count)
				goto rfid_error_retry6;
		}		
		
		//b,read keypad SN	
		for(i=0;i<nfc->rblock_cnt;i++){
			if( PcdRead(nfc->raddr[i],rtmp)!= MI_OK )
				goto rfid_error_retry5;	//return 0xE2; //
			memcpy(nfc->rbuf[i],rtmp,4);
		}//for		
	
        //--------2020.12.17 从NFC直接获取UID; add by Gavin
        nfc->rbuf[0][0] = card_SN_this[7];
        nfc->rbuf[0][1] = card_SN_this[6];
        nfc->rbuf[0][2] = card_SN_this[5];
        nfc->rbuf[0][3] = card_SN_this[4];

        nfc->rbuf[1][0] = card_SN_this[3];
        nfc->rbuf[1][1] = card_SN_this[2];
        nfc->rbuf[1][2] = card_SN_this[1];
        nfc->rbuf[1][3] = card_SN_this[0];        
        //-------------------------------------

		memcpy(card_SN_last,card_SN_this,CARD_SN_LEN);
		return 0x12; //return MI_OK;
		//----------------------------------------------------------------------------

rfid_error_retry1:	
rfid_error_retry2:	
rfid_error_retry3:	
rfid_error_retry4:	
rfid_error_retry5:
rfid_error_retry6:
	return 0xE2; //
		
}
#else
int nfc_write_read_N_block(struct nfc_app_STR *nfc)	
{
		unsigned char card_type[2];
		unsigned char card_SN[4]; 
		unsigned char card_SN_this[CARD_SN_LEN];
		unsigned char i,rtmp[16],tmp[16];	

   //寻卡，----得到卡的类型0x4400
    if(  PcdRequest(PICC_REQALL, card_type) != MI_OK){
			if(++error_count>=10){
				error_count=0;
				memset(card_SN_last,0,CARD_SN_LEN);
			}
			return 0xE0; //return MI_ERR;	
		}
		/* 	FM11NT 	---0x44 , 0x00
				M1			---0x04 ,					//白卡
		*/	
		
		//更改为M0卡的防冲撞流程 YSY 2019.10.14
    //防冲撞,----得到  卡片序列号，4字节
    if( PcdAnticoll(0x93, card_SN) != MI_OK)
        return 0xE1; //return MI_ERR;goto rfid_error1;
		memcpy(card_SN_this,card_SN,4);
    //选卡--INPUT 卡片的序列号4字节!!
    if(  PcdSelect(0x93, card_SN)!= MI_OK)
        return 0xE1; //goto rfid_error1;
    if(  PcdAnticoll(0x95, card_SN)!= MI_OK)
        return 0xE1; //goto rfid_error1;
		memcpy(card_SN_this+4,card_SN,4);		
    //选卡--INPUT 卡片的序列号4字节!!
    if(  PcdSelect(0x95, card_SN) != MI_OK)
        return 0xE1; //goto rfid_error1;
		
		#ifdef 	_NFC_DEBUG_		
		nfc->debug_driver_keep_cnt++;
		#endif					
		error_count =0;
		if(memcmp(card_SN_this,card_SN_last,CARD_SN_LEN) ==0)						
			return 1;	//tag保持add by Gavin 便于外部做应用			
		//---------------------------------------------------------------------	
		#ifdef 	_NFC_DEBUG_		
		nfc->debug_driver_start_cnt++;
		#endif
#if 0	
		//a,write 
		for(i=0;i<nfc->wblock_cnt;i++){
			//a1, read
			if(PcdRead(nfc->waddr[i],rtmp)!= MI_OK)
				goto rfid_error_retry1;				
			//a2,  modify
			memcpy(rtmp,nfc->wbuf[i],4);							
			//a3,write 
			PcdWrite(nfc->waddr[i], rtmp);
			mDelay(50);
			if(PcdWrite(nfc->waddr[i], rtmp) != MI_OK)
				goto rfid_error_retry2;
			mDelay(50);
			
			//a4,read then check them		
			if(PcdRead(nfc->waddr[i],tmp)!= MI_OK)
				goto rfid_error_retry3;
			if( memcmp(rtmp,tmp,4) !=0 )
				goto rfid_error_retry4;				
		}//for
#else		
		//a,write 
		for(i=0;i<nfc->wblock_cnt;i++){
			//a1, read
			if(PcdRead(nfc->waddr[i],rtmp)!= MI_OK)
				goto rfid_error_retry1;				
			//a2,  modify
			memcpy(rtmp,nfc->wbuf[i],4);							
			//a3,write 
			if(PcdWrite(nfc->waddr[i], rtmp) != MI_OK)
				goto rfid_error_retry2;			
		}//for

		////a4,read then check them	
		for(i=0;i<nfc->wblock_cnt;i++){			
			if(PcdRead(nfc->waddr[i],tmp)!= MI_OK)
				goto rfid_error_retry3;
			if( memcmp(nfc->wbuf[i],tmp,4) !=0 )
				goto rfid_error_retry4;				
		}//for

		//20201016 add by Gavin 修改次数
		if(nfc->card_write_cnt_addr !=0){
			unsigned int r_count,w_count=0;
			if(PcdRead(nfc->card_write_cnt_addr,tmp)!= MI_OK)
				goto rfid_error_retry6;
			w_count =(tmp[0]<<24)+(tmp[1]<<16)+(tmp[2]<<8)+(tmp[3]<<0) +1;
			tmp[0] = w_count>>24;
			tmp[1] = w_count>>16;
			tmp[2] = w_count>>8;
			tmp[3] = w_count>>0;
			if(PcdWrite(nfc->card_write_cnt_addr, tmp) != MI_OK)
				goto rfid_error_retry6;	
			
			//read and check 
			if(PcdRead(nfc->card_write_cnt_addr,tmp)!= MI_OK)
				goto rfid_error_retry6;
			r_count =(tmp[0]<<24)+(tmp[1]<<16)+(tmp[2]<<8)+(tmp[3]<<0);
			if( w_count != r_count)
				goto rfid_error_retry6;
		}		
#endif
		
		//b,read keypad SN	
		for(i=0;i<nfc->rblock_cnt;i++){
			if( PcdRead(nfc->raddr[i],rtmp)!= MI_OK )
				goto rfid_error_retry5;	//return 0xE2; //
			memcpy(nfc->rbuf[i],rtmp,4);
		}//for		
		#ifdef 	_NFC_DEBUG_		
		nfc->debug_driver_ok_cnt++;
		memcpy(nfc->card_sn,card_SN_this,CARD_SN_LEN);
		#endif		
		memcpy(card_SN_last,card_SN_this,CARD_SN_LEN);
		return 0x12; //return MI_OK;
		//----------------------------------------------------------------------------
		
#ifdef 	_NFC_DEBUG_	
rfid_error_retry1:
		memcpy(nfc->error[1].card_sn[nfc->error[1].cnt],card_SN_this,CARD_SN_LEN);	
		nfc->error[1].cnt++;
		return 0xE2; //		
rfid_error_retry2:
		memcpy(nfc->error[2].card_sn[nfc->error[2].cnt],card_SN_this,CARD_SN_LEN);	
		nfc->error[2].cnt++;
		return 0xE2; //			
rfid_error_retry3:	
		memcpy(nfc->error[3].card_sn[nfc->error[3].cnt],card_SN_this,CARD_SN_LEN);	
		nfc->error[3].cnt++;
		return 0xE2; //			
rfid_error_retry4:	
		memcpy(nfc->error[4].card_sn[nfc->error[4].cnt],card_SN_this,CARD_SN_LEN);	
		nfc->error[4].cnt++;
		return 0xE2; //			
rfid_error_retry5:		
		memcpy(nfc->error[5].card_sn[nfc->error[5].cnt],card_SN_this,CARD_SN_LEN);	
		nfc->error[5].cnt++;
		return 0xE2; //
rfid_error_retry6:
		memcpy(nfc->error[6].card_sn[nfc->error[6].cnt],card_SN_this,CARD_SN_LEN);	
		nfc->error[6].cnt++;
		return 0xE2; //		
#else
rfid_error_retry1:	
rfid_error_retry2:	
rfid_error_retry3:	
rfid_error_retry4:	
rfid_error_retry5:
rfid_error_retry6:
	return 0xE2; //
#endif			
}

#endif 

//////////////////////////////////////////////////////////////////////
//??RC632?????
//////////////////////////////////////////////////////////////////////
static int M500PcdConfigISOType(unsigned char type)
{
    if (type == 'A'){ //ISO14443_A  
			ClearBitMask(Status2Reg, 0x08);
			WriteRawRC(RxSelReg, 0x86); //84
			WriteRawRC(RFCfgReg, 0x7F);  //4F
			WriteRawRC(TReloadRegL, 30); //tmoLength);// TReloadVal = 'h6a =tmoLength(dec)
			WriteRawRC(TReloadRegH, 0);
			WriteRawRC(TModeReg, 0x8D);
			WriteRawRC(TPrescalerReg, 0x3E);
			WriteRawRC(TxAutoReg, 0x40); //Force100ASK(???)//add by Gavin

			mDelay(100);
			PcdAntennaOn();
    }
    else{
       return MI_NOTAGERR;//-1;
    }

    return MI_OK;
}





/*
* initinal RFid card enter;		*/
void rfid_init(void)
{
    SPI_InitIO();
    PcdReset();
    PcdAntennaOff(); //关闭天线
    PcdAntennaOn();  //开启天线

    M500PcdConfigISOType('A');
}

//unsigned char testx;
/*
* this function using check rfid reader connect or not 
*/
unsigned char get_rfid_reader_Hard_connect_status(void)
{
	//testx =ReadRawRC(RFCfgReg);
	
	return ( (ReadRawRC(RFCfgReg)==0x7F)?1:0);
}






/*
* rfid reader-- debug only 
*/
unsigned char nfc_reader(unsigned char addr,unsigned char cnt,unsigned char *out)	
{
		unsigned char card_type[2];
		unsigned char card_SN[4]; 
		unsigned char card_SN_this[CARD_SN_LEN];
		unsigned char i;//,rtmp[16],tmp[16];	

   //寻卡，----得到卡的类型0x4400
    if(  PcdRequest(PICC_REQALL, card_type) != MI_OK){
			if(++error_count>=10){
				error_count=0;
				memset(card_SN_last,0,CARD_SN_LEN);
			}
			return 0xE0; //return MI_ERR;	
		}
		/* 	FM11NT 	---0x44 , 0x00
				M1			---0x04 ,					//白卡
		*/	
		
		//更改为M0卡的防冲撞流程 YSY 2019.10.14
    //防冲撞,----得到  卡片序列号，4字节
    if( PcdAnticoll(0x93, card_SN) != MI_OK)
        return 0xE1; //return MI_ERR;goto rfid_error1;
		memcpy(card_SN_this,card_SN,4);
    //选卡--INPUT 卡片的序列号4字节!!
    if(  PcdSelect(0x93, card_SN)!= MI_OK)
        return 0xE1; //goto rfid_error1;
    if(  PcdAnticoll(0x95, card_SN)!= MI_OK)
        return 0xE1; //goto rfid_error1;
		memcpy(card_SN_this+4,card_SN,4);		
    //选卡--INPUT 卡片的序列号4字节!!
    if(  PcdSelect(0x95, card_SN) != MI_OK)
        return 0xE1; //goto rfid_error1;
						
		error_count =0;
		if(memcmp(card_SN_this,card_SN_last,CARD_SN_LEN) ==0)						
			return 1;	//tag保持add by Gavin 便于外部做应用		
		
		//b,read keypad SN	
		for(i=0;i<cnt;i++){
			if( PcdRead(addr+i,out+(i<<2))!= MI_OK )
				goto rfid_error_reader;	//return 0xE2; //
		}//for
	
		memcpy(card_SN_last,card_SN_this,CARD_SN_LEN);
		return 0x12; //return MI_OK;
		//----------------------------------------------------------------------------
	
		rfid_error_reader:
			return 0xE0;
}












#endif 
