📄 m500auc.c
字号:
#define M500_GLOBALS
#include <string.h>
#include <stdio.h>
#include <absacc.h>
#include <intrins.h>
#include "Mfreg500.h"
#include "MfErrNo.h"
#include "reg52.h"
#include "M500AuC.h"
#define GetRegPage(addr) (0x80 | (addr>>3))
#define nocard 0
#define mifare1 1
#define mifarepro 2
#define mifarelight 3
#define unknowncard 4
#define NO_TIMER2 1
///////////////////////////////////////////////////////////////////////
// 往一个地址写一个数据
///////////////////////////////////////////////////////////////////////
void WriteRawIO(unsigned char Address,unsigned char value)
{
unsigned int Add;
Add = Address & 0x7fff;
XBYTE[Add] = value;
//XBYTE[Address] = value;
}
///////////////////////////////////////////////////////////////////////
// 从一个地址读出一个数据
///////////////////////////////////////////////////////////////////////
unsigned char ReadRawIO(unsigned char Address)
{
unsigned int Add;
Add = Address & 0x7fff;
return XBYTE[Add];
//return XBYTE[Address];
}
///////////////////////////////////////////////////////////////////////
// 往一个地址写一个数据(EEPROM)
///////////////////////////////////////////////////////////////////////
void WriteIO(unsigned char Address, unsigned char value)
{
WriteRawIO(0x00,GetRegPage(Address));
WriteRawIO(Address,value);
}
///////////////////////////////////////////////////////////////////////
// 从一个地址读出一个数据(EEPROM)
///////////////////////////////////////////////////////////////////////
unsigned char ReadIO(unsigned char Address)
{
WriteRawIO(0x00,GetRegPage(Address));
return ReadRawIO(Address);
}
///////////////////////////////////////////////////////////////////////
// 设置定时时间
///////////////////////////////////////////////////////////////////////
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)
//Mifare定义在ISO14443请求命令
///////////////////////////////////////////////////////////////////////
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);
}
///////////////////////////////////////////////////////////////////////
// Value format operations for Mifare Standard card ICs
///////////////////////////////////////////////////////////////////////
char M500PiccValue(unsigned char dd_mode,
unsigned char addr,
unsigned char *value,
unsigned char trans_addr)
{
char status = MI_OK;
M500PcdSetTmo(1);
ResetInfo(MInfo);
SerBuffer[0] = dd_mode;
SerBuffer[1] = addr;
MInfo.nBytesToSend = 2;
status = M500PcdCmd(PCD_TRANSCEIVE,
SerBuffer,
&MInfo);
if (status != MI_NOTAGERR)
{
if (MInfo.nBitsReceived != 4)
{
status = MI_BITCOUNTERR;
}
else
{
SerBuffer[0] &= 0x0f;
switch(SerBuffer[0])
{
case 0x00:
status = MI_NOTAUTHERR;
break;
case 0x0a:
status = MI_OK;
break;
case 0x01:
status = MI_VALERR;
break;
default:
status = MI_CODEERR;
break;
}
}
}
if ( status == MI_OK)
{
M500PcdSetTmo(3);
ResetInfo(MInfo);
memcpy(SerBuffer,value,4);
MInfo.nBytesToSend = 4;
status = M500PcdCmd(PCD_TRANSCEIVE,
SerBuffer,
&MInfo);
if (status == MI_OK)
{
if (MInfo.nBitsReceived != 4)
{
status = MI_BITCOUNTERR;
}
else
{
SerBuffer[0] &= 0x0f;
switch(SerBuffer[0])
{
case 0x00:
status = MI_NOTAUTHERR;
break;
case 0x01:
status = MI_VALERR;
break;
default:
status = MI_CODEERR;
break;
}
}
}
else
{
if (status == MI_NOTAGERR )
status = MI_OK;
}
}
if (status == MI_OK)
{
ResetInfo(MInfo);
SerBuffer[0] = PICC_TRANSFER;
SerBuffer[1] = trans_addr;
MInfo.nBytesToSend = 2;
status = M500PcdCmd(PCD_TRANSCEIVE,
SerBuffer,
&MInfo);
if (status != MI_NOTAGERR)
{
if (MInfo.nBitsReceived != 4)
{
status = MI_BITCOUNTERR;
}
else
{
SerBuffer[0] &= 0x0f;
switch(SerBuffer[0])
{
case 0x00:
status = MI_NOTAUTHERR;
break;
case 0x0a:
status = MI_OK;
break;
case 0x01:
status = MI_VALERR;
break;
default:
status = MI_CODEERR;
break;
}
}
}
}
return status;
}
///////////////////////////////////////////////////////////////////////
// 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 重新设置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;
}
///////////////////////////////////////////////////////////////
// Key loading into the MF RC500's EEPROM
//下载密码到MF RC500的 EEPROM
///////////////////////////////////////////////////////////////
char M500PcdLoadKeyE2(unsigned char key_type,
unsigned char sector,
unsigned char *uncoded_keys)
{
signed char status = MI_OK;
unsigned int e2addr = 0x80 + sector * 0x18;
unsigned char coded_keys[12];
if (key_type == PICC_AUTHENT1B)
{
e2addr += 12; // key B offset
}
if ((status = M500HostCodeKey(uncoded_keys,coded_keys)) == MI_OK)
{
status = PcdWriteE2(e2addr,12,coded_keys);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -