#include <stdlib.h>
#include <string.h>
#include "stdio.h"
#include <stdint.h>
#include "iso14443_4.h"
#include "rfid.h"
#include "ws18xxx_interface_driver.h"
#include "app_trace.h"

#define FWI_DEFAULT	4
// 14443-4
#define PICC_RATS			  0xE0				 //Request for Answer To Select
#define PICC_NAK			  0xB2         // no CID
#define FWI_DEFAULT	4	//

//#define XDATA xdata 

pcd_info_s   g_pcd_module_info; 


unsigned short  gausMaxFrameSizeTable[] = 
{
    16,  24,  32,  40,  48,  64,  96,  128, 256, 
    256, 256, 256, 256, 256, 256, 256, 256, 256,
};

void pcd_default_info(void) // 
{
	memset(&g_pcd_module_info, 0, sizeof(g_pcd_module_info));
	g_pcd_module_info.ui_fsc = 32;
	g_pcd_module_info.ui_fwi = FWI_DEFAULT;
	g_pcd_module_info.ui_sfgi = 0;
	g_pcd_module_info.uc_nad_en = 0;
	g_pcd_module_info.uc_cid_en = 0;
	g_pcd_module_info.uc_wtxm = 1; //multi
		
}

int pcd_rats_a(unsigned char CID, unsigned char *ats)
{
    int status = MI_OK;
	
    transceive_buffer  *pi;
	
	unsigned char  * ATS;
//	bit ta,tb,tc;
	unsigned int 	ta,tb,tc;				  
	pi = &mf_com_data;
	ta = tb = tc  = 0;

	/*initialiszed the PCB*/
  g_pcd_module_info.uc_pcd_pcb  = 0x02;
  g_pcd_module_info.uc_picc_pcb = 0x03;
  g_pcd_module_info.uc_cid = CID;
	pcd_delay_sfgi(g_pcd_module_info.ui_sfgi);
	PcdSetTmo(4); //according to 14443-4 4.8ms
	
  WriteRawRC(BitFramingReg,0x00);	// // Tx last bits = 0, rx align = 0
	SetBitMask(TxModeReg, BIT7); //使能发送crc
	SetBitMask(RxModeReg, BIT7); //使能接收crc
	
  mf_com_data.mf_command = PCD_TRANSCEIVE;
  mf_com_data.mf_length  = 2;
  mf_com_data.mf_data[0] = PICC_RATS; //Start byte
  mf_com_data.mf_data[1] = (FSDI << 4) + CID; //Parameter

	status = pcd_com_transceive(pi);

	if ( (status == MI_OK && (pi->mf_length % 8) != 0)
		|| (status == MI_COLLERR)
		|| (status == MI_INTEGRITY_ERR && pi->mf_length / 8 < 4)
		|| (status == MI_INTEGRITY_ERR && pi->mf_length / 8 >= 4 && (pi->mf_length % 8) != 0) 
	)
	{
		//printf("2\n");
		status = MI_NOTAGERR; 
	}
	if (MI_OK == status)
	{
		user_print_hex("rx : ", mf_com_data.mf_data ,mf_com_data.mf_length/8); 
	 dbg_printf("\n");
		//ATS
		ATS = pi->mf_data;
		ats[0] = ATS[0];
		ats[1] = ATS[1];
		ats[2] = ATS[2];
		if (pi->mf_length / 8 < 1 || ATS[0] != pi->mf_length / 8)
		{//at least 1bytes, and	TL = length		
			//printf("4\n");
			return PROTOCOL_ERR;
		}
			
		if ( (ATS[0] < (2 + ((ATS[1]&BIT4)>>4) + ((ATS[1]&BIT5)>>5) + ((ATS[1]&BIT6)>>6))))
		{//ERR:TL length
			//return PROTOCOL_ERR;
		}
		else
		{
			if (!(ATS[1]&BIT7))
			{//T0.7 = 0
				if (ATS[1]&BIT4)
				{
					ta = 1;
				}
				if (ATS[1]&BIT5)
				{
					tb = 1;
					g_pcd_module_info.ui_fwi = (ATS[2+(unsigned char)ta] & 0xF0) >> 4;
					g_pcd_module_info.ui_sfgi = ATS[2+(unsigned char)ta] & 0x0f;
					
				}
				if (ATS[1]&BIT6)
				{
					tc = 1;
//					g_pcd_module_info.uc_cid_en = ATS[4] & 0x02; 
//					g_pcd_module_info.uc_nad_en = ATS[4] & 0x01;					
				}
				g_pcd_module_info.ui_fsc = gausMaxFrameSizeTable[ATS[1] & 0x0F];

				//FSC
				if (pi->mf_length/8 < (2 + (unsigned char)ta + (unsigned char)tb + (unsigned char)tc))
				{//长度错误
					return PROTOCOL_ERR;
				}
				PcdSetTmo(g_pcd_module_info.ui_fwi);
			}
			else
			{
				//status = PROTOCOL_ERR;
			}
		}
	}
  if (status == MI_OK)
	{
	
	
	}

	return status;
}


/**
 ****************************************************************
 * @brief pcd_set_rate() 
 *
 * 用于设置非接通信速率（A/B/F）
 *
 * @param: rate = 速率参数
 * @param: type = 协议类型
 * @return: NULL
 ****************************************************************
 */
void pcd_set_rate(unsigned char rate, unsigned char type)
{
	unsigned char val,rxwait;

	switch(rate)
	{
		case '1':
			ClearBitMask(TxModeReg, BIT4 | BIT5 | BIT6);
			ClearBitMask(RxModeReg, BIT4 | BIT5 | BIT6);
			WriteRawRC(ModWidthReg, 0x26);//Miller Pulse Length
			WriteRawRC(RxSelReg, 0x88);
			break;

		case '2':
			ClearBitMask(TxModeReg, BIT4 | BIT5 | BIT6);
			SetBitMask(TxModeReg, BIT4);
			ClearBitMask(RxModeReg, BIT4 | BIT5 | BIT6);
			SetBitMask(RxModeReg, BIT4);
			WriteRawRC(ModWidthReg, 0x12);//Miller Pulse Length
			//rxwait 106 beilv
			val = ReadRawRC(RxSelReg);
			rxwait = ((val & 0x3F)*2);
			if (rxwait > 0x3F)
			{
				rxwait = 0x3F;
			}			
			WriteRawRC(RxSelReg,(rxwait | (val & 0xC0)));
			if(type == 'F')		
			{
				WriteRawRC(RxSelReg, 0x98);
				WriteRawRC(ModWidthReg, 0x15);	
			}
			break;

		case '4':			
			ClearBitMask(TxModeReg, BIT4 | BIT5 | BIT6);
			SetBitMask(TxModeReg, BIT5);
			ClearBitMask(RxModeReg, BIT4 | BIT5 | BIT6);
			SetBitMask(RxModeReg, BIT5);
			WriteRawRC(ModWidthReg, 0x0A);//Miller Pulse Length
			//rxwait
			val = ReadRawRC(RxSelReg);
			rxwait = ((val & 0x3F)*4);
			if (rxwait > 0x3F)
			{
				rxwait = 0x3F;
			}			
			WriteRawRC(RxSelReg,(rxwait | (val & 0xC0)));	

			if(type == 'B')
			{
				 WriteRawRC(0x37, 0xAE);
				 WriteRawRC(0x32, 0x6D);
				 WriteRawRC(0x37, 0x00);
			}
			else if(type == 'F')		//ZZQ20220304-->F此处仅配置了速率，CRC及felica使能请在初始化进行配置
			{
				WriteRawRC(RxSelReg, 0x98);
				WriteRawRC(ModWidthReg, 0x0A);	
			}
			break;
		case '8':			
			ClearBitMask(TxModeReg, BIT4 | BIT5 | BIT6);
			SetBitMask(TxModeReg, BIT4 | BIT5);
			ClearBitMask(RxModeReg, BIT4 | BIT5 | BIT6);
			SetBitMask(RxModeReg, BIT4 | BIT5);
			if(type == 'B')
			{
				 WriteRawRC(0x37, 0xAE);
				 WriteRawRC(0x32, 0x6D);
				 WriteRawRC(0x37, 0x00);
			}
			WriteRawRC(ModWidthReg, 0x04);//Miller Pulse Length
				//rxwait相对于106基本速率需增加相应倍数
			val = ReadRawRC(RxSelReg);
			rxwait = ((val & 0x3F)*8);
			if (rxwait > 0x3F)
			{
				rxwait = 0x3F;
			}			
			WriteRawRC(RxSelReg,(rxwait | (val & 0xC0)));	
			break;
				
		default:
			ClearBitMask(TxModeReg, BIT4 | BIT5 | BIT6);
			ClearBitMask(RxModeReg, BIT4 | BIT5 | BIT6);
			WriteRawRC(ModWidthReg, 0x26);//Miller Pulse Length
			
			break;
	}

	{//不同速率选择不同带宽
		unsigned char adc;
		WriteRawRC(0x37, 0x00);
		adc = ReadRawRC(0x37);

		if (adc == 0x12)
		{
			WriteRawRC(0x37, 0x5E); //?????
			
			if (rate == '8' || rate == '4')//848k,424k
			{
				WriteRawRC(0x3B, 0x25);
			}
			else if (rate == '2' || rate == '1')// 212k, 106k
			{
				WriteRawRC(0x3B, 0xE5);
			}
		}
	}
}

/**
 ****************************************************************
 * @brief pcd_pps_rate() 
 *
 * 功能：向ISO14443-4卡发送COS命令
 *
 *
 ****************************************************************
 */

int pcd_pps_rate(unsigned char *ATS, unsigned char CID, unsigned char rate)
{
	unsigned char DRI, DSI;
	int status = MI_OK;
  transceive_buffer  *pi;
#if (0)
	printf("PPS:\n");
#endif 

	DRI = 0;
	DSI = 0;

	if ((ATS[0] > 1) && (ATS[1] & BIT5))
    {//TA(1) transmited
    	if (rate == 1)
    	{
			
    	}
    	else if (rate == 2)
    	{
			//printf("212K\n");
			if((ATS[2]&BIT0) && (ATS[2]&BIT4))
			{// DS=2,DR=2 supported 212kbps
				DRI = 1;
				DSI = 1;
			}
			else
			{
				//printf(",Unsupport\n");
				return USER_ERROR;
			}	
    	}
		else if (rate == 3)
		{
			//printf("424K\n");
			if((ATS[2]&BIT1) && (ATS[2]&BIT5))
			{// DS=4,DR=4 supported 424kbps
				DRI = 2;
				DSI = 2;
			}
			else
			{
				//printf(",Unsupport\n");
				return USER_ERROR;
			}
		}
		else if (rate == 4)
		{
			//printf("848K\n");
			if((ATS[2]&BIT2) && (ATS[2]&BIT6))
			{// DS=4,DR=4 supported 424kbps
				DRI = 3;
				DSI = 3;
			}
			else
			{
				//printf(",Unsupport\n");
				return USER_ERROR;
			}
		}
		else
		{		
			//printf("USER:No Rate select\n");
			return USER_ERROR;
		}
		WriteRawRC(BitFramingReg,0x00);	// // Tx last bits = 0, rx align = 0
		SetBitMask(TxModeReg, BIT7); //使能发送crc
		SetBitMask(RxModeReg, BIT7); //使能接收crc
	
		pi->mf_command = PCD_TRANSCEIVE;
	    pi->mf_length  = 3;
	    pi->mf_data[0] = (0x0D << 4) + CID; //Start byte
	    pi->mf_data[1] = 0x01 | BIT4; //PPS0 ;BIT4:PPS1 transmited
	    pi->mf_data[2] = (DSI << 2) | DRI; //PPS1
		status = pcd_com_transceive(pi);
		if (status == MI_OK)
		{
			if (pi->mf_length == 8 && pi->mf_data[0] == ((0x0D << 4) + CID))
			{//PPS ok
	//			printf("pcd_pps_rate OK\n");
				if (rate == 1)
				{
					//pps到106k
					
				}
				else if (rate == 2)
				{
					//pps到212k
					pcd_set_rate('2', 'A');// 212kbps
				}
				else if (rate == 3)
				{
					//pps到424k
					pcd_set_rate('4', 'A');// 424kbps
				}
				else if (rate == 4)
				{
					//pps到848k
					pcd_set_rate('8', 'A');// 848kbps
				}				
				
			}
		}

	}

	return status;
}


int ISO14443_4_HalfDuplexExchange( struct pcd_info_s *ppcd_info, 
                                   unsigned char *psrc, 
                                   int i_tx_n, 
                                   unsigned char *pdes, 
                                   unsigned int *pi_rx_n )
{    
	
    unsigned char status;
    int            i_tx_num= 0; 
    int            i_tx_lmt= 0;
    int            i_tx_cn = 0;
    unsigned char* acu_tx_buf = mf_com_data.mf_data;
    unsigned char* acu_rx_buf = mf_com_data.mf_data;
    unsigned char* puc_tx_buf  = acu_tx_buf;
    unsigned char* puc_rx_buf  = acu_rx_buf;
    
    int            i_s_retry   = 0;
    int            i_i_retry   = 0; 
    int            i_err_retry = 0;
    
    unsigned int   ui_wtx	   = 1;

  	int s_swt_limit_count;
	
    enum exe_step_t  e_ex_step;

	  transceive_buffer  *pi;
	  pi = &mf_com_data;
	  

    e_ex_step   = ORG_IBLOCK;
    *pi_rx_n    = 0;
    ui_wtx     = 1;
    i_s_retry   = 0;
    i_i_retry   = 0;
    i_err_retry = 0;
    
    if( ppcd_info->ui_fsc < 16 )ppcd_info->ui_fsc = 32;
    i_tx_lmt = ppcd_info->ui_fsc - 3;
	
    if( ppcd_info->uc_nad_en )i_tx_lmt--;
    if( ppcd_info->uc_cid_en )i_tx_lmt--;
    
    i_tx_num = i_tx_n;
    s_swt_limit_count=0;
    do
    {
        switch( e_ex_step )
        {
        case ORG_IBLOCK:
            puc_tx_buf  = acu_tx_buf;
            
            if( i_tx_num > i_tx_lmt )
            {
                acu_tx_buf[0] = 0x12 | ( ppcd_info->uc_pcd_pcb & ISO14443_CL_PROTOCOL_ISN );
                if( ppcd_info->uc_cid_en )acu_tx_buf[0] |= ISO14443_CL_PROTOCOL_CID;
                if( ppcd_info->uc_nad_en )acu_tx_buf[0] |= ISO14443_CL_PROTOCOL_NAD;
                puc_tx_buf++;
                
                if( ppcd_info->uc_cid_en )*puc_tx_buf++ = ppcd_info->uc_cid & 0x0F;  
                if( ppcd_info->uc_nad_en )*puc_tx_buf++ = ppcd_info->uc_nid & 0x0F;
                
                i_tx_cn    = i_tx_lmt;
                i_tx_num  -= i_tx_lmt;
            }
            else 
            {
                acu_tx_buf[0] = 0x02 | ( ppcd_info->uc_pcd_pcb & ISO14443_CL_PROTOCOL_ISN );
                if( ppcd_info->uc_cid_en )acu_tx_buf[0] |= ISO14443_CL_PROTOCOL_CID;
                if( ppcd_info->uc_nad_en )acu_tx_buf[0] |= ISO14443_CL_PROTOCOL_NAD;
                puc_tx_buf++;
                
                if( ppcd_info->uc_cid_en )*puc_tx_buf++ = ( ppcd_info->uc_cid & 0x0F );  
                if( ppcd_info->uc_nad_en )*puc_tx_buf++ = ( ppcd_info->uc_nid & 0x0F );
                
                i_tx_cn   = i_tx_num;
                i_tx_num  = 0;
            }
            memcpy( puc_tx_buf, psrc, i_tx_cn );
            puc_tx_buf += i_tx_cn;
            psrc   += i_tx_cn;
         
            ppcd_info->uc_pcd_pcb = acu_tx_buf[0];
            
            e_ex_step = ORG_TRARCV;
        break;
        case ORG_ACKBLOCK:
            puc_tx_buf  = acu_tx_buf;
            acu_tx_buf[0] = 0xA2 | ( ppcd_info->uc_pcd_pcb & 1 );
            if( ppcd_info->uc_cid_en )acu_tx_buf[0] |= ISO14443_CL_PROTOCOL_CID;
            puc_tx_buf++;
            if( ppcd_info->uc_cid_en )*puc_tx_buf++ = ( ppcd_info->uc_cid & 0x0F );  
            e_ex_step = ORG_TRARCV;
        break;
        case ORG_NACKBLOCK:
            puc_tx_buf  = acu_tx_buf;
            acu_tx_buf[0] = 0xB2 | ( ppcd_info->uc_pcd_pcb & 1 );
            if( ppcd_info->uc_cid_en )acu_tx_buf[0] |= ISO14443_CL_PROTOCOL_CID;
            puc_tx_buf++;
            if( ppcd_info->uc_cid_en )*puc_tx_buf++ = ( ppcd_info->uc_cid & 0x0F );  
            e_ex_step = ORG_TRARCV;
        break;
        case ORG_SBLOCK:
            puc_tx_buf  = acu_tx_buf;
            *puc_tx_buf++ = 0xF2;
            *puc_tx_buf++ = ui_wtx & 0x3F;  
            e_ex_step = ORG_TRARCV;    
        break;
        case ORG_TRARCV:
           
            i_err_retry++;
            

			if( ui_wtx > 59 )
			{
				ui_wtx = 1;
				e_ex_step = NON_EVENT;
				status = ISO14443_4_ERR_PROTOCOL;
				break;
			}
			
			g_pcd_module_info.uc_wtxm = ui_wtx;


			pcd_delay_sfgi(ppcd_info->ui_sfgi);
			PcdSetTmo(ppcd_info->ui_fwi);
			pi->mf_length = puc_tx_buf - acu_tx_buf;
			memcpy(pi->mf_data, acu_tx_buf, pi->mf_length);
			pi->mf_command = PCD_TRANSCEIVE;
			status = pcd_com_transceive(pi);
			ppcd_info->uc_pcd_txr_num = pi->mf_length / 8 + !!(pi->mf_length % 8);
			memcpy(acu_rx_buf, pi->mf_data, ppcd_info->uc_pcd_txr_num);
			ppcd_info->uc_pcd_txr_lastbits = pi->mf_length % 8;
			
           
            if (status != MI_OK)
            {

                if( i_err_retry > ISO14443_PROTOCOL_RETRANSMISSION_LIMITED ||
                    i_s_retry > ISO14443_PROTOCOL_RETRANSMISSION_LIMITED )
                {
                    e_ex_step = RCV_INVBLOCK;
                }
                else
                {
                    if( ppcd_info->uc_picc_pcb & ISO14443_CL_PROTOCOL_CHAINED )
                    {
                        e_ex_step = ORG_ACKBLOCK;
                    }
                    else
                    {
                        e_ex_step = ORG_NACKBLOCK;  
                    }
                }
            }
            else
            {
                i_err_retry = 0;
                
                if (status == MI_OK)
                {   
                    puc_rx_buf = acu_rx_buf;
                    
                    if( 0x02 == ( acu_rx_buf[0] & 0xE2 ) )
                    {
                        if(( 0 == ( acu_rx_buf[0] & 0x2 ) ) || ( ppcd_info->uc_pcd_txr_num > 254 ))
                        {
                            e_ex_step = RCV_INVBLOCK;
                        }
                        else
                        {
                            i_s_retry = 0;
                            e_ex_step  = RCV_IBLOCK;
                        }
                    }
                    else if( 0xA2 == ( acu_rx_buf[0] & 0xE6 ) )
                    {
                        if( (( ISO14443_CL_PROTOCOL_CID & acu_rx_buf[0] ) && ( ppcd_info->uc_pcd_txr_num != 2 ))
							|| (( !( ISO14443_CL_PROTOCOL_CID & acu_rx_buf[0] ) ) && ( ppcd_info->uc_pcd_txr_num != 1 ))
                          )
                        {    
                            e_ex_step = RCV_INVBLOCK;
                        }
                        else
                        {
                            i_s_retry = 0;
                            e_ex_step  = RCV_RBLOCK;
                        }
                    }
                    else if( 0xC2 == ( acu_rx_buf[0] & 0xC7 ) )
                    {   
                        if( (( ISO14443_CL_PROTOCOL_CID & acu_rx_buf[0] ) && ( ppcd_info->uc_pcd_txr_num != 3 ))
							|| (( !( ISO14443_CL_PROTOCOL_CID & acu_rx_buf[0] ) ) && ( ppcd_info->uc_pcd_txr_num != 2 ))
                          )
                        {    
                            e_ex_step = RCV_INVBLOCK;
                        }
                        else
                        {
                            i_s_retry++;
                            e_ex_step = RCV_SBLOCK;
                        }
                    }
                    else 
                    {
                        e_ex_step = RCV_INVBLOCK;
                    }
                }
                else
                {
                    
                }
            }
            
 	
            ui_wtx       = 1;
			g_pcd_module_info.uc_wtxm = ui_wtx;
        break;
        case RCV_IBLOCK:
            if( i_tx_num )
            {
                e_ex_step = RCV_INVBLOCK;
            }
            else
            {
                puc_rx_buf++;
                
                
                if( ( ppcd_info->uc_pcd_pcb & ISO14443_CL_PROTOCOL_ISN ) == 
                    ( acu_rx_buf[0] & ISO14443_CL_PROTOCOL_ISN ) )
                {   
                    ppcd_info->uc_picc_pcb = acu_rx_buf[0];
                    
                    if( acu_rx_buf[0] & ISO14443_CL_PROTOCOL_CHAINED )
                    {
                        if( acu_rx_buf[0] & ISO14443_CL_PROTOCOL_CID )puc_rx_buf++;
                        if( acu_rx_buf[0] & ISO14443_CL_PROTOCOL_NAD )puc_rx_buf++;
                         
                        
                        e_ex_step = ORG_ACKBLOCK;
                    }
                    else
                    {
                        if( acu_rx_buf[0] & ISO14443_CL_PROTOCOL_CID )puc_rx_buf++;
                        if( acu_rx_buf[0] & ISO14443_CL_PROTOCOL_NAD )puc_rx_buf++;
                        
                        e_ex_step = NON_EVENT;   
                    }
                    
                    
                    if( ppcd_info->uc_pcd_txr_num >= ( puc_rx_buf - acu_rx_buf ) )
                    {
                        memcpy( pdes, puc_rx_buf, ( ppcd_info->uc_pcd_txr_num - ( puc_rx_buf - acu_rx_buf ) ) );
                        pdes  += ppcd_info->uc_pcd_txr_num - ( puc_rx_buf - acu_rx_buf );
                        *pi_rx_n  += ppcd_info->uc_pcd_txr_num - ( puc_rx_buf - acu_rx_buf );
                    }
                    
                    ppcd_info->uc_pcd_pcb ^= ISO14443_CL_PROTOCOL_ISN;
                }
                else 
                {
                    e_ex_step = RCV_INVBLOCK;   
                }
            }
        break;
        case RCV_RBLOCK:
            if( acu_rx_buf[0] & 0x10 )
            {
                e_ex_step = RCV_INVBLOCK;
            }
            else
            {
                
                if( ( ppcd_info->uc_pcd_pcb & ISO14443_CL_PROTOCOL_ISN ) == 
                    ( acu_rx_buf[0] & ISO14443_CL_PROTOCOL_ISN ) )
                {
                    
                    if( ppcd_info->uc_pcd_pcb & ISO14443_CL_PROTOCOL_CHAINED )
                    {   
                        ppcd_info->uc_pcd_pcb ^= ISO14443_CL_PROTOCOL_ISN;
                        
                        i_i_retry = 0;
                        e_ex_step = ORG_IBLOCK;
                    }
                    else
                    {
                        e_ex_step = RCV_INVBLOCK; 
                    }
                }
                else 
                {
                    i_i_retry++;
                    
                    if( i_i_retry > ISO14443_PROTOCOL_RETRANSMISSION_LIMITED )
                    {
                        e_ex_step = RCV_INVBLOCK;     
                    }
                    else
                    {
                        i_tx_num += i_tx_cn;
                        psrc -= i_tx_cn;
                        e_ex_step = ORG_IBLOCK;
                    }
                }
            }
        break;
        case RCV_SBLOCK:
            if( 0xF2 != ( acu_rx_buf[0] & 0xF7 ) )
            {
                e_ex_step = RCV_INVBLOCK;
            }
            else
            {
                puc_rx_buf = acu_rx_buf + 1;
                if( acu_rx_buf[0] & ISO14443_CL_PROTOCOL_CID )puc_rx_buf++;
                if( 0 == ( *puc_rx_buf & 0x3F ) )
                {
                    e_ex_step = RCV_INVBLOCK;
                }
                else
                {
                    s_swt_limit_count++;
                    ui_wtx = ( *puc_rx_buf & 0x3F );
                    e_ex_step = ORG_SBLOCK;
                }
            }
        break;
        case RCV_INVBLOCK:

			if (MI_NOTAGERR != status)
			{
				status = ISO14443_4_ERR_PROTOCOL;
			}
			e_ex_step = NON_EVENT;
            
        break;
        default:
        break;
        }
    }while( NON_EVENT != e_ex_step );

    return status;
}



int iso14443_4_deselect(unsigned char CID)
{
    int status;
    
	transceive_buffer  *pi;
    pi = &mf_com_data;

	dbg_printf("iso14443_4_deselect : \n");
	  PcdSetTmo(4);
    mf_com_data.mf_command = PCD_TRANSCEIVE;
    mf_com_data.mf_length  = 2;
    mf_com_data.mf_data[0] = 0xca;
    mf_com_data.mf_data[1] = CID & 0x0f;
    status = pcd_com_transceive(pi);
    return status;
}

int com_typea_rats(unsigned char pps_pcmd)
{
	char status;
	unsigned char CID = 0;
	unsigned char ats[3];
	unsigned char rate;   
//	transceive_buffer  *pi;
//	pi = &mf_com_data;

	status = pcd_rats_a(CID, ats);
	if(status == MI_OK)
	{
		dbg_printf("rats : ok \n");
#if 0		
 	if(pps_pcmd != 0)
		{
			rate = pps_pcmd;
			status = pcd_pps_rate(pi, ats, CID, rate);
		}
#endif
	}

	if (status != MI_OK)
	{
	  	dbg_printf("rats : fail:\n");
     		return MI_ERR;
	}
 return status;
}

/**
 ****************************************************************
 * @brief APUD() 
 *
 * 14443A_4 APDU接口调试指令函数
 *
 * @param: addr 寄存器地址
 * @return: c 寄存器的值
 ****************************************************************
 */
int APDU(void)
{
	int status;
	
  uint8_t  tx_buff[] = {0x00, 0xA4, 0x00, 0x00, 0x02, 0x3F, 0x00};  //00A4040010F0000000485750415906000022050001
	uint8_t  rx_buff[20];
  unsigned int  rx_len;
	
  if(status == MI_OK)
	{
		dbg_printf("apdu :\n");
	  status = ISO14443_4_HalfDuplexExchange(&g_pcd_module_info, tx_buff, 7, rx_buff, &rx_len);
    if (status == MI_OK) ///
	  {
	  	user_print_hex("rx : ", rx_buff ,rx_len); 
	  	dbg_printf("\n");
	  }
	}
	
	return status;
}




