📄 mifare.c
字号:
//#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 + -