📄 mfr500.c
字号:
///////////////////////////////////////////////////////////////////////
// 设置定时时间
///////////////////////////////////////////////////////////////////////
void M500PcdSetTmo(unsigned char tmoLength)
{
switch (tmoLength) {
case 1:
WriteIO(RegTimerClock, 0x07);
WriteIO(RegTimerReload, 0x6a);
break;
case 2:
WriteIO(RegTimerClock, 0x07);
WriteIO(RegTimerReload, 0xa0);
break;
case 3:
WriteIO(RegTimerClock, 0x09);
WriteIO(RegTimerReload, 0xa0);
break;
case 4:
WriteIO(RegTimerClock, 0x09);
WriteIO(RegTimerReload, 0xff);
break;
case 5:
WriteIO(RegTimerClock, 0x0b);
WriteIO(RegTimerReload, 0xff);
break;
case 6:
WriteIO(RegTimerClock, 0x0d);
WriteIO(RegTimerReload, 0xff);
break;
case 7:
WriteIO(RegTimerClock, 0x0f);
WriteIO(RegTimerReload, 0xff);
break;
default:
WriteIO(RegTimerClock, 0x07);
WriteIO(RegTimerReload, tmoLength);
break;
}
}
///////////////////////////////////////////////////////////////////////
// Request Command defined in ISO14443(Mifare)
///////////////////////////////////////////////////////////////////////
char M500PcdCmd(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;
WriteIO(RegInterruptEn, 0x7F);
WriteIO(RegInterruptRq, 0x7F);
WriteIO(RegCommand, PCD_IDLE);
FlushFIFO();
MpIsrInfo = info;
MpIsrOut = rcv;
info->irqSource = 0x00;
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 = -(ReadIO(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 = -(ReadIO(RegBitFraming) >> 4);
irqEn = 0x3D;
waitFor = 0x04;
break;
default:
status = MI_UNKNOWN_COMMAND;
}
if (status == MI_OK) {
irqEn |= 0x20;
waitFor |= 0x20;
timecnt = 1000;
WriteIO(RegInterruptEn, irqEn | 0x80);
WriteIO(RegCommand, cmd);
while (!(MpIsrInfo->irqSource & waitFor || !(timecnt--)));
WriteIO(RegInterruptEn, 0x7F);
WriteIO(RegInterruptRq, 0x7F);
SetBitMask(RegControl, 0x04);
WriteIO(RegCommand, PCD_IDLE);
if (!(MpIsrInfo->irqSource & waitFor)) {
status = MI_ACCESSTIMEOUT;
} else {
status = MpIsrInfo->status;
}
if (status == MI_OK) {
if (tmpStatus = (ReadIO(RegErrorFlag) & 0x17)) {
if (tmpStatus & 0x01) {
info->collPos = ReadIO(RegCollPos);
status = MI_COLLERR;
} else {
info->collPos = 0;
if (tmpStatus & 0x02) {
status = MI_PARITYERR;
}
}
if (tmpStatus & 0x04) {
status = MI_FRAMINGERR;
}
if (tmpStatus & 0x10) {
FlushFIFO();
status = MI_OVFLERR;
}
if (tmpStatus & 0x08) {
status = MI_CRCERR;
}
if (status == MI_OK)
status = MI_NY_IMPLEMENTED;
}
if (cmd == PCD_TRANSCEIVE) {
lastBits = ReadIO(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;
return status;
}
///////////////////////////////////////////////////////////////////////
// 置一个bit
///////////////////////////////////////////////////////////////////////
char SetBitMask(unsigned char reg, unsigned char mask)
{
char idata tmp = 0x00;
tmp = ReadIO(reg);
WriteIO(reg, tmp | mask); // set bit mask
return 0x00;
}
///////////////////////////////////////////////////////////////////////
// 清一个bit
///////////////////////////////////////////////////////////////////////
char ClearBitMask(unsigned char reg, unsigned char mask)
{
char idata tmp = 0x00;
tmp = ReadIO(reg);
WriteIO(reg, tmp & ~mask); // clear bit mask
return 0x00;
}
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
void FlushFIFO(void)
{
SetBitMask(RegControl, 0x01);
}
///////////////////////////////////////////////////////////////////////
// Set card in HALT-state
// 终止卡的操作
///////////////////////////////////////////////////////////////////////
/*char M500PiccHalt(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 = M500PcdCmd(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
WriteIO(RegCommand,PCD_IDLE);
return status;
} */
///////////////////////////////////////////////////////////////////////
// Reset the MF RC500
///////////////////////////////////////////////////////////////////////
char M500PcdReset(void)
{
char idata status = MI_OK;
unsigned int idata timecnt = 0;
RC500RST = 0;
delay_1ms(25);
RC500RST = 1;
delay_50us(200);
RC500RST = 0;
delay_50us(50);
timecnt = 1000;
while ((ReadIO(RegCommand) & 0x3F) && timecnt--);
if (!timecnt) {
status = MI_RESETERR;
}
if (status == MI_OK) {
//WriteIO(RegPage,0x80);
if (ReadIO(RegCommand) != 0x00) {
status = MI_INTERFACEERR;
}
}
return status;
}
///////////////////////////////////////////////////////////////////////
// Configures the MF RC500 配置RC500内部寄存器函数
///////////////////////////////////////////////////////////////////////
char M500PcdConfig(void)
{
char idata status;
if ((status = M500PcdReset()) == MI_OK) {
WriteIO(RegClockQControl, 0x00);
WriteIO(RegClockQControl, 0x40);
delay_50us(2);
ClearBitMask(RegClockQControl, 0x40);
WriteIO(RegBitPhase, 0xAD);
WriteIO(RegRxThreshold, 0xFF);
WriteIO(RegRxControl2, 0x01);
WriteIO(RegFIFOLevel, 0x1A);
WriteIO(RegTimerControl, 0x02);
WriteIO(RegIRqPinConfig, 0x03);
M500PcdRfReset(1);
}
return status;
}
///////////////////////////////////////////////////////////////////////
// Select Command defined in ISO14443(MIFARE)
///////////////////////////////////////////////////////////////////////
char M500PcdMfOutSelect(unsigned char type)
{
WriteIO(RegMfOutSelect, type & 0x7);
return MI_OK;
}
///////////////////////////////////////////////////////////////////////
// Request Command defined in ISO14443(MIFARE)
// Request,Anticoll,Select,return CardType(2 bytes)+CardSerialNo(4 bytes)
// 寻卡,防冲突,选择卡 返回卡类型(2 bytes)+ 卡系列号(4 bytes)
///////////////////////////////////////////////////////////////////////
char M500PiccCommonRequest(unsigned char req_code, unsigned char* atq)
{
char idata status = MI_OK;
M500PcdSetTmo(3);
WriteIO(RegChannelRedundancy, 0x03);
ClearBitMask(RegControl, 0x08);
WriteIO(RegBitFraming, 0x07);
SetBitMask(RegTxControl, 0x03);
ResetInfo(MInfo);
SerBuffer[0] = req_code;
MInfo.nBytesToSend = 1;
status = M500PcdCmd(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;
}
///////////////////////////////////////////////////////////////////
// Cascaded Anti-Collision Command defined in ISO14443(MIFARE)
// 防冲突 读卡的系列号 MLastSelectedSnr
///////////////////////////////////////////////////////////////////
char M500PiccCascAnticoll(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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -