📄 mf_rc500.c
字号:
#include "MF_RC500.h"
#include "MF_Func.h"
void RC_WriteRawData(unsigned char Address,unsigned char value)
{XBYTE[Address]=value;}
unsigned char RC_ReadRawData(unsigned char Address)
{return XBYTE[Address];}
//write to mfrc500
void RC_WriteRC(unsigned char Address, unsigned char value)
{
RC_WriteRawData(0x0,GetRegPage(Address));
RC_WriteRawData(Address,value);
}
//read from mfrc500
unsigned char RC_ReadRC(unsigned char Address)
{
RC_WriteRawData(0x0,GetRegPage(Address));
return RC_ReadRawData(Address);
}
void RC_SetTmod(unsigned char tmoLength)
{
switch(tmoLength)
{
case tmod_1ms: // 1ms
RC_WriteRC(RegTimerClock,0x07);
RC_WriteRC(RegTimerReload,0x6a);
break;
case tmod_1_5ms: // 1.5ms
RC_WriteRC(RegTimerClock,0x07);
RC_WriteRC(RegTimerReload,0xa0);
break;
case tmod_6ms: // 6ms
RC_WriteRC(RegTimerClock,0x09);
RC_WriteRC(RegTimerReload,0xa0);
break;
case tmod_9_6ms: //9.6ms
RC_WriteRC(RegTimerClock,0x09);
RC_WriteRC(RegTimerReload,0xff);
break;
default:
RC_WriteRC(RegTimerClock,0x07);
RC_WriteRC(RegTimerReload,tmoLength);
break;
}
}
char RC_Command(unsigned char cmd,
volatile unsigned char data *rcv,
MfCmdInfo idata *info)
{
char idata status = MI_OK;
char idata tmpStatus ;
unsigned char idata lastBits;
unsigned int idata timecnt=0;
unsigned char idata irqEn = 0x00;
unsigned char idata waitFor = 0x00;
unsigned char idata timerCtl = 0x00;
RC_WriteRC(RegInterruptEn,0x7F);
RC_WriteRC(RegInterruptRq,0x7F);
RC_WriteRC(RegCommand,PCD_IDLE);
RC_FlushFIFO();
MpIsrInfo = info;
MpIsrOut = rcv;
info->irqSource = 0x0;
switch(cmd)
{
case PCD_IDLE:
irqEn = 0x00;
waitFor = 0x00;
break;
case PCD_WRITEE2:
irqEn = 0x11;
waitFor = 0x10;
break;
case PCD_READE2:
irqEn = 0x07;
waitFor = 0x04;
break;
case PCD_LOADCONFIG:
case PCD_LOADKEYE2:
case PCD_AUTHENT1:
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_CALCCRC:
irqEn = 0x11;
waitFor = 0x10;
break;
case PCD_AUTHENT2:
irqEn = 0x04;
waitFor = 0x04;
break;
case PCD_RECEIVE:
info->nBitsReceived = -(RC_ReadRC(RegBitFraming) >> 4);
irqEn = 0x06;
waitFor = 0x04;
break;
case PCD_LOADKEY:
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_TRANSMIT:
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_TRANSCEIVE:
info->nBitsReceived = -(RC_ReadRC(RegBitFraming) >> 4);
irqEn = 0x3D;
waitFor = 0x04;
break;
default:
status = MI_UNKNOWN_COMMAND;
}
if (status == MI_OK)
{
irqEn |= 0x20;
waitFor |= 0x20;
timecnt=1000;
RC_WriteRC(RegInterruptEn,irqEn | 0x80);
RC_WriteRC(RegCommand,cmd);
while (!(MpIsrInfo->irqSource & waitFor||!(timecnt--)));
RC_WriteRC(RegInterruptEn,0x7F);
RC_WriteRC(RegInterruptRq,0x7F);
RC_SetBit(RegControl,0x04);
RC_WriteRC(RegCommand,PCD_IDLE);
if (!(MpIsrInfo->irqSource & waitFor))
{
status = MI_ACCESSTIMEOUT;
}
else
status = MpIsrInfo->status;
if (status == MI_OK)
{
if (tmpStatus = (RC_ReadRC(RegErrorFlag) & 0x17))
{
if (tmpStatus & 0x01)
{
info->collPos = RC_ReadRC(RegCollPos);
status = MI_COLLERR;
}
else
{
info->collPos = 0;
if (tmpStatus & 0x02)
{
status = MI_PARITYERR;
}
}
if (tmpStatus & 0x04)
{
status = MI_FRAMINGERR;
}
if (tmpStatus & 0x10)
{
RC_FlushFIFO();
status = MI_OVFLERR;
}
if (tmpStatus & 0x08)
{
status = MI_CRCERR;
}
if (status == MI_OK)
status = MI_NY_IMPLEMENTED;
}
if (cmd == PCD_TRANSCEIVE)
{
lastBits = RC_ReadRC(RegSecondaryStatus) & 0x07;
if (lastBits)
info->nBitsReceived += (info->nBytesReceived-1) * 8 + lastBits;
else
info->nBitsReceived += info->nBytesReceived * 8;
}
}
else
{
info->collPos = 0x00;
}
}
MpIsrInfo = 0;
MpIsrOut = 0;
MpIsrOut = 0;
return status;
}
char RC_SetBit(unsigned char reg,unsigned char mask) //
{
char idata tmp = 0x0;
tmp = RC_ReadRC(reg);
RC_WriteRC(reg,tmp | mask); // set bit mask
return 0x0;
}
char RC_ClearBit(unsigned char reg,unsigned char mask) //
{
char idata tmp = 0x0;
tmp = RC_ReadRC(reg);
RC_WriteRC(reg,tmp & ~mask); // clear bit mask
return 0x0;
}
void RC_FlushFIFO(void)
{
RC_SetBit(RegControl,0x01);
}
// M I F A R E H A L T
char MF_Halt(void)
{
char idata status = MI_CODEERR;
// ************* Cmd Sequence **********************************
ResetInfo(MInfo);
SerBuffer[0] = PICC_HALT ; // Halt command code
SerBuffer[1] = 0x00; // dummy address
MInfo.nBytesToSend = 2;
status = RC_Command(PCD_TRANSCEIVE,
SerBuffer,
&MInfo);
if (status)
{
// timeout error ==> no NAK received ==> OK
if (status == MI_NOTAGERR || status == MI_ACCESSTIMEOUT)
status = MI_OK;
}
//reset command register - no response from tag
RC_WriteRC(RegCommand,PCD_IDLE);
return status;
}
char MF_Reset(void)
{
char idata status = MI_OK;
unsigned int idata timecnt=0;
RC500RST = 0;
delay_1ms(50);
RC500RST = 1;
delay_1ms(20);
RC500RST = 0;
delay_1ms(20);
timecnt=1000;
while ((RC_ReadRC(RegCommand) & 0x3F)&&timecnt--);
if(!timecnt)
status = MI_RESETERR;
if (status == MI_OK)
{
RC_WriteRC(RegPage,0x80);
timecnt=1000;
while (RC_ReadRC(RegCommand)&&timecnt--);
if(!timecnt)
status = MI_INTERFACEERR;
RC_WriteRC(RegPage,0x00);
timecnt=1000;
while (RC_ReadRC(RegCommand)&&timecnt--);
if(!timecnt)
status = MI_INTERFACEERR;
/*
if (RC_ReadRC(RegCommand) != 0x00)
{
status = MI_INTERFACEERR;
}
*/
}
return status;
}
void MF_Config(void)
{
if (MF_Reset()!= MI_OK)
while(1)
{
LED1=0;
WDG=!WDG;
}
RC_WriteRC(RegClockQControl,0x0);
RC_WriteRC(RegClockQControl,0x40);
delay_50us(2);
RC_ClearBit(RegClockQControl,0x40);
RC_WriteRC(RegBitPhase,0xAD);
RC_WriteRC(RegRxThreshold,0xFF);
RC_WriteRC(RegRxControl2,0x01);
RC_WriteRC(RegFIFOLevel,0x1A);
RC_WriteRC(RegTimerControl,0x02);
RC_WriteRC(RegIRqPinConfig,0x03);
RC_WriteRC(RegMfOutSelect,2&0x7);
MF_RfReset(1);
}
char MF_Request(unsigned char req_code,unsigned char *atq)
{
char idata status = MI_OK;
RC_SetTmod(tmod_6ms);
RC_WriteRC(RegChannelRedundancy,0x03);
RC_ClearBit(RegControl,0x08);
RC_WriteRC(RegBitFraming,0x07);
RC_SetBit(RegTxControl,0x03);
ResetInfo(MInfo);
SerBuffer[0] = req_code;
MInfo.nBytesToSend = 1;
status = RC_Command(PCD_TRANSCEIVE,SerBuffer,&MInfo);
if (status)
*atq = 0;
else
{
if (MInfo.nBitsReceived != 16)
{
*atq = 0;
status = MI_BITCOUNTERR;
}
else
{
status = MI_OK;
memcpy(atq,SerBuffer,2);
}
}
return status;
}
char MF_Conflict (unsigned char bcnt,
unsigned char *snr)
{
char idata status = MI_OK;
char idata snr_in[4];
char idata nbytes = 0;
char idata nbits = 0;
char idata complete = 0;
char idata i = 0;
char idata byteOffset = 0;
unsigned char dummyShift1;
unsigned char dummyShift2;
RC_SetTmod(tmod_1ms);
memcpy(snr_in,snr,4);
RC_WriteRC(RegDecoderControl,0x28);
RC_ClearBit(RegControl,0x08);
complete = 0;
while (!complete && (status == MI_OK) )
{
ResetInfo(MInfo);
RC_WriteRC(RegChannelRedundancy,0x03);
nbits = bcnt % 8;
if (nbits)
{
RC_WriteRC(RegBitFraming,nbits << 4 | nbits);
nbytes = bcnt / 8 + 1;
if (nbits == 7)
{
MInfo.cmd = PICC_ANTICOLL1;
RC_WriteRC(RegBitFraming,nbits);
}
}
else
{
nbytes = bcnt / 8;
}
SerBuffer[0] = 0x93;
SerBuffer[1] = 0x20 + ((bcnt/8) << 4) + nbits;
for (i = 0; i < nbytes; i++)
{
SerBuffer[i + 2] = snr_in[i];
}
MInfo.nBytesToSend = 2 + nbytes;
status = RC_Command(PCD_TRANSCEIVE,
SerBuffer,
&MInfo);
if (nbits == 7)
{
dummyShift1 = 0x00;
for (i = 0; i < MInfo.nBytesReceived; i++)
{
dummyShift2 = SerBuffer[i];
SerBuffer[i] = (dummyShift1 >> (i+1)) | (SerBuffer[i] << (7-i));
dummyShift1 = dummyShift2;
}
MInfo.nBitsReceived -= MInfo.nBytesReceived;
if ( MInfo.collPos ) MInfo.collPos += 7 - (MInfo.collPos + 6) / 9;
}
if ( status == MI_OK || status == MI_COLLERR)
{
if ( MInfo.nBitsReceived != (40 - bcnt) )
{
status = MI_BITCOUNTERR;
}
else
{
byteOffset = 0;
if( nbits != 0 )
{
snr_in[nbytes - 1] = snr_in[nbytes - 1] | SerBuffer[0];
byteOffset = 1;
}
for ( i =0; i < (4 - nbytes); i++)
{
snr_in[nbytes + i] = SerBuffer[i + byteOffset];
}
if (status != MI_COLLERR )
{
dummyShift2 = snr_in[0] ^ snr_in[1] ^ snr_in[2] ^ snr_in[3];
dummyShift1 = SerBuffer[MInfo.nBytesReceived - 1];
if (dummyShift2 != dummyShift1)
{
status = MI_SERNRERR;
}
else
{
complete = 1;
}
}
else
{
bcnt = bcnt + MInfo.collPos - nbits;
status = MI_OK;
}
}
}
}
if (status == MI_OK)
{
memcpy(snr,snr_in,4);
}
else
{
memcpy(snr,"0000",4);
}
RC_ClearBit(RegDecoderControl,0x20);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -