📄 mfrc500.c
字号:
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)
{
// Initialize uC Timer for global Timeout management
irqEn |= 0x20; // always enable timout irq
waitFor |= 0x20; // always wait for timeout
WriteIO(RegInterruptEn,irqEn | 0x80); //necessary interrupts are enabled // count up from 1
WriteIO(RegCommand,cmd); //start command
starttime = GetTickCount();
// wait for commmand completion
// a command is completed, if the corresponding interrupt occurs
// or a timeout is signaled
while (!(MpIsrInfo->irqSource & waitFor
|| T3IR)); // wait for cmd completion or timeout
WriteIO(RegInterruptEn,0x7F); // disable all interrupts
WriteIO(RegInterruptRq,0x7F); // clear all interrupt requests
SetBitMask(RegControl,0x04); // stop timer now
GT_vStopTmr(TIMER_4);
GT_vStopTmr(TIMER_3);
LED_OFF;
T3IR = 0;
WriteIO(RegCommand,PCD_IDLE); // reset command register
if (!(MpIsrInfo->irqSource & waitFor)) // reader has not terminated
{ // timer 3 expired
status = MI_ACCESSTIMEOUT;
}
else
status = MpIsrInfo->status; // set status
if (status == MI_OK) // no timeout error occured
{
if ((tmpStatus = (ReadIO(RegErrorFlag) & 0x17))) // error occured
{
if (tmpStatus & 0x01) // collision detected
{
info->collPos = ReadIO(RegCollPos); // read collision position
status = MI_COLLERR;
}
else
{
info->collPos = 0;
if (tmpStatus & 0x02) // parity error
{
status = MI_PARITYERR;
}
}
if (tmpStatus & 0x04) // framing error
{
status = MI_FRAMINGERR;
}
if (tmpStatus & 0x10) // FIFO overflow
{
FlushFIFO();
status = MI_OVFLERR;
}
if (tmpStatus & 0x08) // CRC error
{
status = MI_CRCERR;
}
if (status == MI_OK)
status = MI_NY_IMPLEMENTED;
// key error occures always, because of
// missing crypto 1 keys loaded
}
// if the last command was TRANSCEIVE, the number of
// received bits must be calculated - even if an error occured
if (cmd == PCD_TRANSCEIVE || cmd == PCD_RECEIVE)
{
// number of bits in the last byte
lastBits = ReadIO(RegSecondaryStatus) & 0x07;
if (lastBits)
info->nBitsReceived += (info->nBytesReceived-1) * 8 + lastBits;
else
info->nBitsReceived += info->nBytesReceived * 8;
}
}
else
{
info->collPos = 0x00;
}
}
READER_INT_DISABLE;
PcdIsrFct = EmptyPcdIsrFct; // reset the ISR-Function pointer to
// an empty function body
// do this before clearing the Mp XXXX variables
MpIsrInfo = 0; // reset interface variables for ISR
MpIsrOut = 0;
MpIsrIn = 0;
return status;
}
#endif
/********************************
* set mfrc500 receive gain *
********************************/
void M500SetRcvGain(uchar gain)
{
if(gain > 3)
gain = 3;
RxGain = gain + 0x70;
WriteIO(RegRxControl1, RxGain);//73:42db, 72:38, 71:30, 70:27
M500PcdRfReset(5);
}
/********************************
* init mfrc500 *
********************************/
uchar M500PcdInit(void)
{
uchar miret = MI_OK;
IT0 = 1; // edge
SetIntPri(IE0_VECTOR, 2);
miret = M500PcdReset();
#ifdef FORCE_RESET
if(miret != MI_OK)
return miret;
#endif
WriteIO(RegClockQControl,0x00);
WriteIO(RegClockQControl,0x40);
SoftDelayCyl(100);
ClearBitMask(RegClockQControl,0x40); ////
// WriteIO(RegTxControl, 0x5b);//////////////////////////////////
// The following values for RegBitPhase and
// RegRxThreshold represents an optimal
// value for our demo package. For user
// implementation some changes could be
// necessary
// initialize bit phase
WriteIO(RegBitPhase,0xAD);
// initialize minlevel
WriteIO(RegRxThreshold,0xFF);
// disable auto power down
//WriteIO(RegRxControl2,0x01);
WriteIO(RegRxControl2,0x01);//C1 for Power saving, 01 for disable auto power down
//WriteIO(RegDecoderControl,0x28);/////////////////////////////////////////////
WriteIO(RegRxControl1,RxGain);//73:42db, 72:38, 71:30, 70:27///////////////////
// Depending on the processing speed of the
// operation environment, the waterlevel
// can be adapted. (not very critical for
// mifare applications)
// initialize waterlevel to value 4
WriteIO(RegFIFOLevel,0x1a); // 4 // 1a
//Timer configuration
WriteIO(RegTimerControl,0x02); // TStopRxEnd=0,TStopRxBeg=0, 2
// TStartTxEnd=1,TStartTxBeg=0
// timer must be stopped manually
WriteIO(RegIRqPinConfig,0x03); // interrupt active low enable
M500PcdRfReset(5); // Rf - reset and enable output driver //1-2
return miret;
/*
//芯片可配置选项
WriteIO(RegClockQControl,0x0);
WriteIO(RegClockQControl,0x40);
delay(2);// wait approximately 50ms(>100us) - calibration in progress
//ClearBitMask(RegClockQControl,0x40); // clear bit ClkQCalib for further calibration
WriteIO(RegBitPhase,0xAD);// initialize bit phase
WriteIO(RegRxThreshold,0xFF);// initialize minlevel
//WriteIO(RegRxControl2,01);// disable auto power down
WriteIO(RegTimerControl,0x0a);//TStartTxEnd=1,TStopRxEnd=1
WriteIO(RegIRqPinConfig,0x3); // interrupt active low enable
ClearBitMask(RegTxControl,0x03); // Tx2RF-En, Tx1RF-En disable
delay(2); // Delay for 1 ms
WriteIO(RegTxControl,0x5b);
WriteIO(RegRxControl1,0x72);//38db
WriteIO(RegRxControl2,0xC1);//41);//Power saving
WriteIO(RegDecoderControl,0x28);
WriteIO(RegTimerClock,0x07);
WriteIO(RegRxThreshold,0xff);////
WriteIO(RegFIFOLevel,0x01);///
//初始状态
WriteIO(RegInterruptRq,0x7F);//clear all inter
//WriteIO(RegInterruptEn,0xFF);//enable all interrupts
WriteIO(RegCommand,PCD_IDLE);
SetBitMask(RegControl,0x01);//FlushFIFO
SetBitMask(RegControl,0x04);//StopTimer
WriteIO(RegInterruptEn,0x7f);
WriteIO(RegInterruptEn,0x88);//RC500只开接收中断
*/
}
/********************************
* mfrc500 reset *
* ms: time between clr and set *
********************************/
void M500PcdRfReset(uchar ms)
{
ClearBitMask(RegTxControl,0x03);
if(ms > 0)
{
delay(ms + 1);
SetBitMask(RegTxControl,0x03);
}
}
uchar M500PcdReset(void)
{
unsigned int starttime;
unsigned char rdval = 0;
// first reset by the rst pin
M500Reset();
// wait until reset command recognized
starttime = GetTickCount();
while (ReadRawIO(RegCommand) & 0x3F != 0x3F)
{
if(GetTickCount() - starttime >= 200)
{
#ifndef FORCE_RESET
return MI_RESETERR;
#else
rdval = MI_RESETERR;
break;
#endif
}
}
// while reset sequence in progress
starttime = GetTickCount();
while (ReadRawIO(RegCommand) & 0x3F)
{
if(GetTickCount() - starttime >= 200)
{
#ifndef FORCE_RESET
return MI_RESETERR;
#else
rdval = MI_RESETERR;
break;
#endif
}
}
WriteRawIO(RegPage,0x80); // Dummy access in order to determine the bus
// configuration
// necessary read access
// after first write access, the returned value
// should be zero ==> interface recognized
if (ReadRawIO(RegCommand) != 0x00)
{
rdval = MI_INTERFACEERR;
}
WriteRawIO(RegPage,0x00); // configure to linear address mode
return rdval;
}
/********************************
* SET DEFAULT COMM ATTRIB *
********************************/
uchar M500PcdSetDefaultAttrib(void)
{
uchar status = MI_OK;
/*
WriteRawIO(RegTimerClock,0x07);
WriteRawIO(RegInterruptRq,0x7F);//clear all inter
SetBitMask(RegControl,0x04); //StopTimer
WriteRawIO(RegTxControl,0x5b);
//WriteRawRC(RegInterruptEn,0x7F);//disable all interrupts
//WriteRawRC(RegInterruptEn,0x88);
//WriteRawRC(RegChannelRedundancy,0x00); //no parity, no crc ; 03, en parity
//ClearBitMask(RegControl,0x08); // disable crypto 1 unit
//WriteRawRC(RegBitFraming,0x07); // set TxLastBits to 7
WriteRawIO(RegInterruptEn,0x7f);
//WriteRawRC(RegInterruptEn,0x88);
FlushFIFO();*/
return status;
}
/********************************
* mfrc500 request card *
* req_code: type of request *
* atq: answer to request *
********************************/
uchar M500Request(uchar req_code, uchar *atq)
{
uchar idata status = MI_OK;
M500PcdSetDefaultAttrib();
// ClearBitMask(RegTxControl,0x03); // 050418
// delay(2); // same as upon
WriteIO(RegChannelRedundancy,0x03); // 03
ClearBitMask(RegControl,0x08);
WriteIO(RegBitFraming,0x07);
// M500PcdRfReset(3); ///////////// 050418
ResetInfo(&MInfo);
SndBuffer[0] = req_code;
MInfo.nBytesToSend = 1;
M500PcdSetTmo(3); // 2 050418 设置时间为6.0ms
status = M500PcdCmd(PCD_TRANSCEIVE, SndBuffer, RcvBuffer, &MInfo);
if (status)
{
*atq = 0;
}
else
{
if (MInfo.nBitsReceived != 16)
{
*atq = 0;
status = MI_BITCOUNTERR;
}
else
{
status = MI_OK;
memcpy(atq, RcvBuffer, 2);
}
}
return status;
}
uchar M500Anticoll(uchar *Snr)
{
register uchar i;
uchar idata status = MI_OK;
uchar idata nbytes = 0;
uchar idata bcnt = 0;
uchar idata nbits = 0;
uchar idata complete = 0;
uchar idata byteOffset = 0;
uchar idata snr_crc;
uchar idata snr_check;
uchar idata dummyShift1;
uchar idata dummyShift2;
M500PcdSetDefaultAttrib();
M500PcdSetTmo(2); // 1 050418
WriteIO(RegDecoderControl,0x28);
ClearBitMask(RegControl,0x08);
complete = 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)
{
MInfo.cmd = PICC_ANTICOLL1;
WriteIO(RegBitFraming,nbits);
}
}
else
{
nbytes = bcnt / 8;
}
SndBuffer[0] = 0x93;
SndBuffer[1] = 0x20 + ((bcnt/8) << 4) + nbits;
for (i = 0; i < nbytes; i++)
{
SndBuffer[i + 2] = Snr[i];
}
MInfo.nBytesToSend = 2 + nbytes;
status = M500PcdCmd(PCD_TRANSCEIVE, SndBuffer, RcvBuffer, &MInfo);
if (nbits == 7)
{
dummyShift1 = 0x00;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -