📄 function.c
字号:
///////////////////////////////////////////////////////////////////////////////
#include <Mfreg500.h>
#include <M500A.h>
#include <string.h>
extern void delay_50us(unsigned char time);
// reset struct
#define ResetInfo(info) \
info.nBytesToSend = 0; \
info.nBytesSent = 0; \
info.nBytesReceived = 0; \
info.nBitsReceived = 0; \
info.irqSource = 0; \
info.collPos = 0;
// struct definition for a communication channel
typedef struct
{
unsigned char nBytesToSend; // how many bytes to send
unsigned char nBytesSent; // how many bytes sent
unsigned char nBytesReceived;// how many bytes received
unsigned int nBitsReceived; // how many bits received
unsigned char irqSource; //
unsigned char collPos; // at which position occured a collision
} MfCmdInfo;
static unsigned char idata MFIFOLength = DEF_FIFO_LENGTH; // actual FIFO length
// send buffer
static volatile unsigned char MSndBuffer[SND_BUF_LEN];
// receive buffer
static volatile unsigned char MRcvBuffer[RCV_BUF_LEN];
// info struct
static volatile MfCmdInfo MInfo;
extern void WriteIO(unsigned char add,unsigned char value);
extern unsigned char ReadIO(unsigned char add);
char SetBitMask(unsigned char reg,unsigned char mask) //
{
char idata tmp = 0x0;
tmp = ReadIO(reg) | mask;
WriteIO(reg,tmp);
return 0x0;
}
char ClearBitMask(unsigned char reg,unsigned char mask)
{
char idata tmp = 0x0;
tmp = ReadIO(reg) & ~mask;
WriteIO(reg,tmp); // clear bit mask
return 0x0;
}
void FlushFIFO(void)
{
SetBitMask(RegControl,0x01);
}
void RC500Config(void)
{
while ((ReadIO(RegCommand) & 0x3F) == 0x3F); // 接口初始化检查
WriteIO(RegPage,0x80);
while ((ReadIO(RegCommand) & 0x3F) == 0x3F);
WriteIO(RegPage,0x00); // 线性地址模式
WriteIO(RegClockQControl,0x00);
WriteIO(RegClockQControl,0x40);
delay_50us(2);
ClearBitMask(RegClockQControl,0x40);
WriteIO(RegBitPhase,0xaa);
WriteIO(RegRxThreshold,0xDF);
WriteIO(RegRxControl2,0x01);
WriteIO(RegRxWait,0x05);
WriteIO(RegFIFOLevel,0x05);
WriteIO(RegTimerControl,0x00);
WriteIO(RegTimerClock,0x10);
WriteIO(RegTimerReload,0x32);
WriteIO(RegInterruptEn,0x7F);
ClearBitMask(RegTxControl,0x03);
delay_50us(20);
SetBitMask(RegTxControl,0x03);
}
char RC500Cmd(unsigned char cmd,
volatile unsigned char* send,
volatile unsigned char* rcv,
volatile MfCmdInfo *info)
{
char idata status = MI_OK;
unsigned char irqBits;
unsigned char lastBits;
unsigned char irqMask;
unsigned char nbytes;
unsigned char cnt;
unsigned char tmpStatus ;
unsigned char irqEn = 0x00;
unsigned char waitFor = 0x00;
unsigned char TimeOut = 0x00;
WriteIO(RegInterruptEn,0x7F);
WriteIO(RegInterruptRq,0x7F);
WriteIO(RegCommand,PCD_IDLE);
FlushFIFO();
switch(cmd)
{
case PCD_IDLE: // nothing else required
irqEn = 0x00;
waitFor = 0x00;
break;
case PCD_WRITEE2: // LoAlert and TxIRq
irqEn = 0x11;
waitFor = 0x10;
break;
case PCD_READE2: // HiAlert, LoAlert and IdleIRq
irqEn = 0x07;
waitFor = 0x04;
break;
case PCD_LOADCONFIG: // IdleIRq
case PCD_LOADKEYE2: // IdleIRq
case PCD_AUTHENT1: // IdleIRq
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_CALCCRC: // LoAlert and TxIRq
irqEn = 0x11;
waitFor = 0x10;
break;
case PCD_AUTHENT2: // IdleIRq
irqEn = 0x04;
waitFor = 0x04;
break;
case PCD_RECEIVE: // HiAlert and IdleIRq
info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4);
irqEn = 0x06;
waitFor = 0x04;
break;
case PCD_LOADKEY: // IdleIRq
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_TRANSMIT: // LoAlert and IdleIRq
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_TRANSCEIVE: // TxIrq, RxIrq, IdleIRq and LoAlert
info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4);
irqEn = 0x3D;
waitFor = 0x04;
break;
default:
status = MI_UNKNOWN_COMMAND;
}
if (status == MI_OK)
{
irqEn |= 0x20;
waitFor |= 0x20;
WriteIO(RegInterruptEn,irqEn | 0x80);
SetBitMask(RegControl,0x02);
WriteIO(RegCommand,cmd);
while (!(info->irqSource & waitFor || TimeOut))
{
while( ReadIO(RegPrimaryStatus) & 0x08)
{
irqMask = ReadIO(RegInterruptEn);
irqBits = ReadIO(RegInterruptRq) & irqMask;
info->irqSource |= irqBits;
if (irqBits & 0x01)
{
nbytes = MFIFOLength - ReadIO(RegFIFOLength);
if ((info->nBytesToSend - info->nBytesSent) <= nbytes)
{
nbytes = info->nBytesToSend - info->nBytesSent;
WriteIO(RegInterruptEn,0x01);
}
for ( cnt = 0;cnt < nbytes;cnt++)
{
WriteIO(RegFIFOData,send[info->nBytesSent]);
info->nBytesSent++;
}
WriteIO(RegInterruptRq,0x01);
}
if (irqBits & 0x10)
{
WriteIO(RegInterruptRq,0x10);
WriteIO(RegInterruptEn,0x82);
if (cmd == PICC_ANTICOLL1)
{
WriteIO(RegChannelRedundancy,0x02);
}
}
if (irqBits & 0x0E)
{
nbytes = ReadIO(RegFIFOLength);
for ( cnt = 0; cnt < nbytes; cnt++)
{
rcv[info->nBytesReceived] = ReadIO(RegFIFOData);
info->nBytesReceived++;
}
WriteIO(RegInterruptRq,0x0A & irqBits);
}
if (irqBits & 0x04)
{
WriteIO(RegInterruptEn,0x20);
WriteIO(RegInterruptRq,0x20);
irqBits &= ~0x20;
info->irqSource &= ~0x20;
WriteIO(RegInterruptRq,0x04);
}
if (irqBits & 0x20)
{
WriteIO(RegInterruptRq,0x20);
status = MI_NOTAGERR;
TimeOut = 1;
break;
}
}
}
WriteIO(RegInterruptEn,0x7F);
WriteIO(RegInterruptRq,0x7F);
SetBitMask(RegControl,0x04);
WriteIO(RegCommand,PCD_IDLE);
if (!(info->irqSource & waitFor))
{
status = MI_ACCESSTIMEOUT;
}
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;
}
}
return status;
}
char PcdReadE2(unsigned int startaddr,
unsigned char length,
unsigned char* _data)
{
char status = MI_OK;
ResetInfo(MInfo);
MSndBuffer[0] = startaddr & 0xFF;
MSndBuffer[1] = (startaddr >> 8) & 0xFF;
MSndBuffer[2] = length;
MInfo.nBytesToSend = 3;
status = RC500Cmd(PCD_READE2,
MSndBuffer,
MRcvBuffer,
&MInfo);
if (status == MI_OK)
{
memcpy(_data,MRcvBuffer,length);
}
else
{
_data[0] = 0;
}
return status ;
}
char CardRequest(unsigned char req_code,
unsigned char *atq)
{
char idata status = MI_OK;
WriteIO(RegChannelRedundancy,0x03);
ClearBitMask(RegControl,0x08);
WriteIO(RegBitFraming,0x07);
SetBitMask(RegTxControl,0x03);
ResetInfo(MInfo);
MSndBuffer[0] = req_code;
MInfo.nBytesToSend = 1;
status = RC500Cmd(PCD_TRANSCEIVE,
MSndBuffer,
MRcvBuffer,
&MInfo);
if (status)
{
*atq = 0;
}
else
{
if (MInfo.nBitsReceived != 16)
{
*atq = 0;
status = MI_BITCOUNTERR;
}
else
{
status = MI_OK;
memcpy(atq,MRcvBuffer,2);
}
}
return status;
}
char ReadCardNum (unsigned char bcnt,
unsigned char *snr)
{
char idata status = MI_OK;
char idata snr_in[4];
char nbytes = 0;
char nbits = 0;
char complete = 0;
char i = 0;
char byteOffset = 0;
unsigned char snr_crc;
unsigned char snr_check;
unsigned char dummyShift1;
unsigned char dummyShift2;
memcpy(snr_in,snr,4);
WriteIO(RegDecoderControl,0x28);
ClearBitMask(RegControl,0x08);
complete = 0;
bcnt = 0;
while (!complete && (status == MI_OK) )
{
ResetInfo(MInfo);
WriteIO(RegChannelRedundancy,0x03);
nbits = bcnt % 8;
if (nbits)
{
WriteIO(RegBitFraming,nbits << 4 | nbits);
nbytes = bcnt / 8 + 1;
if (nbits == 7)
{
WriteIO(RegBitFraming,nbits);
}
}
else
{
nbytes = bcnt / 8;
}
MSndBuffer[0] = 0x93;
MSndBuffer[1] = 0x20 + ((bcnt/8) << 4) + nbits;
for (i = 0; i < nbytes; i++)
{
MSndBuffer[i + 2] = snr_in[i];
}
MInfo.nBytesToSend = 2 + nbytes;
status = RC500Cmd(PCD_TRANSCEIVE,
MSndBuffer,
MRcvBuffer,
&MInfo);
if (nbits == 7)
{
dummyShift1 = 0x00;
for (i = 0; i < MInfo.nBytesReceived; i++)
{
dummyShift2 = MRcvBuffer[i];
MRcvBuffer[i] = (dummyShift1 >> (i+1)) | (MRcvBuffer[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] | MRcvBuffer[0];
byteOffset = 1;
}
for ( i =0; i < (4 - nbytes); i++)
{
snr_in[nbytes + i] = MRcvBuffer[i + byteOffset];
}
if (status != MI_COLLERR )
{
snr_crc = snr_in[0] ^ snr_in[1] ^ snr_in[2] ^ snr_in[3];
snr_check = MRcvBuffer[MInfo.nBytesReceived - 1];
if (snr_crc != snr_check)
{
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);
}
ClearBitMask(RegDecoderControl,0x20);
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -