⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mifare.c

📁 利用NXP的新一代高集成度的芯片RC500完成Mifare系列卡的读写
💻 C
📖 第 1 页 / 共 2 页
字号:
//#include "..\inc\normal.h"
#include "mifare.h"

///////////////////////////////////////////////////////////////////////////////
//          G E N E R I C    W R I T E
///////////////////////////////////////////////////////////////////////////////
void WriteIO(unsigned char Address, unsigned char value)
{ 
	outportb(Gpbase+Address,value);
}

///////////////////////////////////////////////////////////////////////////////
//          G E N E R I C    R E A D
///////////////////////////////////////////////////////////////////////////////
unsigned char ReadIO(unsigned char Address)
{
	return inportb(Gpbase+Address);
	//return (i);
}  

///////////////////////////////////////////////////////////////////////////////
//   S E T   A   B I T   M A S K 
///////////////////////////////////////////////////////////////////////////////
char SetBitMask(unsigned char reg,unsigned char mask) // 
{
   char idata tmp = 0x0;

   tmp = ReadIO(reg);
   WriteIO(reg,tmp | mask);  // set bit mask
   return 0x0;
}

///////////////////////////////////////////////////////////////////////////////
//   C L E A R   A   B I T   M A S K 
///////////////////////////////////////////////////////////////////////////////
char ClearBitMask(unsigned char reg,unsigned char mask) // 
{
   char idata tmp = 0x0;
   tmp = ReadIO(reg);
   WriteIO(reg,tmp & ~mask);  // clear bit mask
   return 0x0;
}
 
///////////////////////////////////////////////////////////////////////////////
//   delay_50us
///////////////////////////////////////////////////////////////////////////////
void delay_50us(unsigned char i)
{
	unsigned char  idata b;
	b=0x01;
	while(i--)
	{
		while(b--);
	}
}  

///////////////////////////////////////////////////////////////////////////////
//   FlushFIFO
///////////////////////////////////////////////////////////////////////////////
void FlushFIFO(void)
{  
   SetBitMask(RegControl,0x01);
}

/****************************************

            RC531

*****************************************/
///////////////////////////////////////////////////////////////////////////////
//   M500PcdReset
///////////////////////////////////////////////////////////////////////////////
char M500PcdReset(void)
{	 
    	char idata status = MI_OK;
    	unsigned char Time;
    	Time=5000;
    	while((ReadIO(RegCommand)&0x3f)!=0)
    	{
    	    Time--;
    	    if(!Time)
    	    {
    	        break;
    	    }
    	}    
      	WriteIO(RegPage,0x80); // Dummy access in order to determine the bus 
      	if (ReadIO(RegCommand) != 0x00)
      	{                           
        	status = MI_INTERFACEERR;
      	}
      	WriteIO(RegPage,0x00); // configure to linear address mode
   return status;
}

/***************************************************************

         RF I/O RESET FUNCTIONS

****************************************************************/
void M500PcdRfReset(unsigned char ms)
{
   //   outport(AUXCON, 0x0083);		//After configuration,things is:  i/o set 8bit mode
   char idata status = 0;   
   if(ms)
   {
     ClearBitMask(RegTxControl,0x03);  // Tx2RF-En, Tx1RF-En disablen
     delay_50us(ms*10);                // Delay for 1 ms
     SetBitMask(RegTxControl,0x03);    // Tx2RF-En, Tx1RF-En enable
   }
   else
     ClearBitMask(RegTxControl,0x03);  // Tx2RF-En, Tx1RF-En disablen
  // return status;
}
//**************************************************************************/

unsigned char M500HostCodeKey(unsigned char *uncoded,unsigned char *coded)      // 6 bytes key value uncoded                                                                        // 12 bytes key value coded
{
   unsigned char  idata cnt = 0;
   unsigned char  idata ln  = 0;     // low nibble
   unsigned char  idata hn  = 0;     // high nibble
   for (cnt = 0; cnt < 6; cnt++)
   {
      ln = uncoded[cnt] & 0x0F;
      hn = uncoded[cnt] >> 4;
      coded[cnt * 2 + 1] = (~ln << 4) | ln;
      coded[cnt * 2 ] = (~hn << 4) | hn;
   }
   return MI_OK;   
}   

//*************************************************************

//              LOADCONFIG COMMAND

// initlise rc531 register files  and rf signals

//**************************************************************/
char  mif_config(void)
{
    if(M500PcdReset() ==0)
    {
        WriteIO(RegControl,0x00);
        WriteIO(RegClockQControl,0x0);
        WriteIO(RegClockQControl,0x40);
        delay_50us(4);  // wait approximately 100 us - calibration in progress
        ClearBitMask(RegClockQControl,0x40); // clear bit ClkQCalib for 
        WriteIO(RegBitPhase,0xAD);      
        WriteIO(RegRxThreshold,0x9d);      
        WriteIO(RegRxWait,0x06);   
        WriteIO(RegRxControl2,0x01);
        WriteIO(RegFIFOLevel,0x04);   
        WriteIO(RegTimerControl,0x02);  // TStopRxEnd=0,TStopRxBeg=1,
        delay_50us(4);//delay_50us(20);       //delay1ms
        WriteIO(RegIRqPinConfig,0x02); // interrupt active low enable
		WriteIO(RegInterruptEn,0x7F); // disable all interrupts
		WriteIO(RegInterruptRq,0x7F); // reset interrupt requests
        M500PcdRfReset(1);            // Rf - reset and enable output driver   
        return MI_OK;
     }
    else 
    	return MI_INTERFACEERR ;
}

/*********************************************************************

              request  COMMAND 

**********************************************************************/
char mif_request2(unsigned char mode,unsigned char *atq)
{
	unsigned char req_code=0;
	unsigned char m_status;
	  
	WriteIO(RegControl,0x00);  
	if(mode)
		req_code=0x52;
	else 
		req_code=0x26;	
 	WriteIO(RegChannelRedundancy,0x03); // RxCRC and TxCRC disable, parity enable
	ClearBitMask(RegControl,0x01);    // disable crypto 1 unit   
	WriteIO(RegBitFraming,0x07);        // set TxLastBits to 7 
	SetBitMask(RegTxControl,0x03);    // Tx2RF-En, Tx1RF-En enable
 	WriteIO(RegCommand,00); // terminate probably running command
 	FlushFIFO();  
	m_status=ReadIO(RegPrimaryStatus);      
    if((m_status&0x60)!=0x00)
        return MI_CHK_FAILED;
	WriteIO(RegFIFOData,req_code);
	WriteIO(RegCommand,0x1e); 
	delay_50us(4);        //delay_50us(20);          //delay 1ms
	m_status=ReadIO(RegPrimaryStatus);	
	WriteIO(RegCommand,00);
    m_status=ReadIO(RegFIFOLength);;           //test fifo length     	
    if(m_status==0x02)
    {
    	*atq++=ReadIO(RegFIFOData);	
    	*atq=ReadIO(RegFIFOData);	
    	return MI_OK;              
    }
    return MI_NOTAGERR;            //no card checked
}

/*****************************************************

          mifare anticoll command

******************************************************/
char mif_anticoll(unsigned char bcnt,unsigned char  *cardsnr)
{
	unsigned char m_status,i,validbit=0;
   	unsigned char snrbuffer[5];
   	unsigned char snrcnt=0,collcntbits=0,fifolength=0;
   	unsigned char colleftbit=0;
	unsigned char checkbcc;
	  
	WriteIO(RegDecoderControl,0x28); // ZeroAfterColl aktivieren   
   	ClearBitMask(RegControl,0x08);   // disable crypto 1 unit
	WriteIO(RegCommand,00);          // terminate probably running command
	FlushFIFO();  
	
	WriteIO(RegChannelRedundancy,0x03); 	// RxCRC and TxCRC disable, parity enable
 	m_status=ReadIO(RegPrimaryStatus);  
 	    
 	if((m_status&0x60)!=0x00)
    		return MI_CHK_FAILED;
    bcnt=0x20;	
	WriteIO(RegFIFOData,0x93);	
	WriteIO(RegFIFOData,bcnt);	 
    WriteIO(RegCommand,0x1e);      	
    delay_50us(6);//delay_50us(30);
    WriteIO(RegCommand,00);
    for(i=0;i<5;i++)
    	snrbuffer[i]=0x00;          //clear the snrbuffer

 	collcntbits=ReadIO(RegCollpos);  //check collision bit is valid or not 	

    fifolength= ReadIO(RegFIFOLength);    //fifo length     	

	m_status = ReadIO(RegErrorFlag);
   	validbit=ReadIO(RegSecondaryStatus);        //judge valid bit
    checkbcc=0;
	if((fifolength==0x05)&(collcntbits==0x00))
    {
        for(i=0;i<fifolength;i++)
		{
			cardsnr[i]=ReadIO(RegFIFOData);
		    checkbcc^=cardsnr[i];
		}
		if (checkbcc==0)
		{
		 	return MI_OK;
		}
		else
		{
			return MI_SERNRERR; 	
		}	
    }
	return MI_BYTECOUNTERR;       
}

/*****************************************************

          mifare select card command

******************************************************/
char mif_select(unsigned char  *serial)
{
   	unsigned char status;
   	unsigned char sum,fifolength;
	unsigned int k=0;
          
	ClearBitMask(RegControl,0x08);      // disable crypto 1 unit
	WriteIO(RegChannelRedundancy,0x0f); // RxCRC and TxCRC disable, parity enable
	WriteIO(RegCommand,00);             // terminate probably running command
	FlushFIFO();  
	status=ReadIO(RegPrimaryStatus);    //
	
	if((status&0x60)!=0x00)
    	return MI_CHK_FAILED;

    //WriteIO(RegFIFOData,0x97); 
	WriteIO(RegFIFOData,0x93);	
	WriteIO(RegFIFOData,0x70);	 
		
	WriteIO(RegFIFOData,*serial);	 
	sum=*serial++;
  	WriteIO(RegFIFOData,*serial);	     //serial[1]
  	sum^=*serial++;
  	WriteIO(RegFIFOData,*serial);	     //serial[2]
 	sum^=*serial++;
	WriteIO(RegFIFOData,*serial);	     //serial[3]
	sum^=*serial;
	WriteIO(RegFIFOData,sum);	         //parity summary
	WriteIO(RegCommand,0x1e);            //A :transmit  //0x1e :transeive
	delay_50us(4);
	WriteIO(RegCommand,00);
	//status=ReadIO(RegPrimaryStatus);     
	
    fifolength= ReadIO(RegFIFOLength);   //fifo length
    	
	if (fifolength==1)
	{
		status=ReadIO(RegFIFOData);
		if(status==0x08)
		{
			return MI_OK;
		}
		else
		{
			return MI_NOTAGERR ; 	
		}
	}
	else
	{
		return MI_BYTECOUNTERR;
	}   
}

/************************************************************

      loadkey command

*************************************************************/
char mif_load_key(unsigned char  *uncodekey)
{
	unsigned char status,i;
	unsigned char keybuffer[12];
     	  
	ClearBitMask(RegControl,0x08);         // disable crypto 1 unit
	WriteIO(RegCommand,00);                // terminate probably running command
	FlushFIFO();  
  	status=M500HostCodeKey(uncodekey,keybuffer);
	if(status==MI_OK)
	{
		for(i=0;i<12;i++)
		WriteIO(RegFIFOData,keybuffer[i]); //write coded keydata into fifo	 
		WriteIO(RegCommand,0x19);          //loadkey command 0x19
		delay_50us(4);                     //delay_50us(20);//delay 1ms
		WriteIO(RegCommand,00);
		status=ReadIO(RegErrorFlag );      //ERROR FLAG REGISTER

		if((status&0x40)==0x00) 
			return MI_OK;                  //operate right
	}
	return MI_KEYERR;	                   //operate wrong
}

/*************************************************************

           mifare authent command

**************************************************************/
char mif_authentication( unsigned char auth_mode,unsigned char sactor,unsigned char *snr)
{
	unsigned char i,status;
	unsigned char MSndBuffer[6];
	unsigned char keyaorb;
	unsigned char block;
     
	block=sactor*4+3;      
	if(auth_mode) keyaorb=0x60;        //keya 验证A密钥
	else keyaorb=0x61;                 //keyb 验证A密钥
      
	MSndBuffer[0] = keyaorb;           // mifare authentication command  authen keya:0x60 keyb:0x61
	MSndBuffer[1] = block;             // write block number for authentication
      	
	for(i=0;i<4;i++)
		MSndBuffer[i+2]=snr[i];        // write 4 bytes card serial number
        	
	ClearBitMask(RegControl,0x08);     // disable crypto 1 unit
	WriteIO(RegCommand,00);            // terminate probably running command  切换至闲转置状态
	
	FlushFIFO();  
	
	status=ReadIO(RegPrimaryStatus);       //读03H,接收器各发送器及FIFO状态 
	if((status&0x60)!=0x00)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -