📄 rc500.c
字号:
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
WriteRC(RegCommand,PCD_IDLE);
return status;
}
void SetBitMask(unsigned int reg,unsigned char mask)
{
unsigned int idata reg1;
unsigned char mask1;
reg1=reg;
mask1=mask;
XBYTE[reg1] |= mask1; // clear bit mask
}
void ClearBitMask(unsigned int reg,unsigned char mask)
{
unsigned char mask1;
mask1=mask;
XBYTE[reg] &= ~mask1; // clear bit mask
}
void FlushFIFO(void)
{
SetBitMask(RegControl,0x01);
}
void WriteRC(unsigned int Address, unsigned char value)
{
XBYTE[Address]=value; // write value at the specified
}
unsigned char ReadRC(unsigned int Address)
{
Returnval=XBYTE[Address]; // read value at the specified
return(Returnval); // address
}
//////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////
void PcdSetTmo(unsigned char tmoLength)
{
switch(tmoLength)
{ // timer clock frequency 13,56 MHz
case 1: // short timeout (1,0 ms)
WriteRC(RegTimerClock,0x07); // TAutoRestart=0,TPrescale=128选择定时器的分频值 如果TAutoRestart设置为1,定时器从
//TReloadValue处自动重新开始向下计数,而不是向下计数到零
WriteRC(RegTimerReload,0x6a);// TReloadVal = 'h6a =106(dec)
break;
case 2: // medium timeout (1,5 ms)
WriteRC(RegTimerClock,0x07); // TAutoRestart=0,TPrescale=128
WriteRC(RegTimerReload,0xa0);// TReloadVal = 'ha0 =160(dec)
break;
case 3: // long timeout (6 ms)
WriteRC(RegTimerClock,0x09); // TAutoRestart=0,TPrescale=4*128
WriteRC(RegTimerReload,0xa0);// TReloadVal = 'ha0 =160(dec)
break;
case 4: // long timeout (9.6 ms)
WriteRC(RegTimerClock,0x09); // TAutoRestart=0,TPrescale=4*128
WriteRC(RegTimerReload,0xff);// TReloadVal = 'ff =255(dec)
break;
case 5:
WriteRC(RegTimerClock,0x01); // TAutoRestart=0,TPrescale=4*128
WriteRC(RegTimerReload,0xff);// TReloadVal = 'ff =255(dec)
default: // short timeout (1,0 ms)
WriteRC(RegTimerClock,0x07); // TAutoRestart=0,TPrescale=128
WriteRC(RegTimerReload,tmoLength);// TReloadVal = tmoLength
break;
}
}
char PcdRfReset(unsigned int nms)
{
char status = MI_OK;
ClearBitMask(RegTxControl,0x03); // Tx2RF-En, Tx1RF-En disablen
if (nms > 0)
{
nms=1000*nms;
Delay(nms);
SetBitMask(RegTxControl,0x03);
}
return status;
}
void ResetInfo(void)
{
MInfo.cmd = 0;
MInfo.status = MI_OK;
MInfo.irqSource = 0;
MInfo.nBytesSent = 0;
MInfo.nBytesToSend = 0;
MInfo.nBytesReceived = 0;
MInfo.nBitsReceived = 0;
MInfo.collPos = 0;
}
char PcdSingleResponseCmd(unsigned char cmd)
{
int i;
char status = MI_OK;
char tmpStatus ;
unsigned char lastBits;
unsigned char irqEn = 0x00;
unsigned char waitFor = 0x00;
unsigned char timerCtl = 0x00;
WriteRC(RegInterruptEn,0x7F); // disable all interrupts
WriteRC(RegInterruptRq,0x7F); // reset interrupt requests
WriteRC(RegCommand,PCD_IDLE); // terminate probably running command
FlushFIFO(); // flush FIFO buffer
// save info structures to module pointers
/* MInfo.cmd=MInfo.cmd;
MInfo.status=MInfo.status;
MInfo.irqSource=MInfo.irqSource;
MInfo.nBytesSent=MInfo.nBytesSent;
MInfo.nBytesToSend=MInfo.nBytesToSend;
MInfo.nBytesReceived=MInfo.nBytesReceived;
MInfo.nBitsReceived=MInfo.nBitsReceived;
MInfo.collPos=MInfo.collPos; */
haveset=1;
// initialising the ISR-Function pointer for mifare
// protocol - do this after initialising the MpXXXX variables
MInfo.irqSource = 0x0; // reset interrupt flags
// depending on the command code, appropriate interrupts are enabled (irqEn)
// and the commit interrupt is choosen (waitFor).
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 and LoAlert
case PCD_LOADKEYE2: // IdleIRq and LoAlert
case PCD_AUTHENT1: // IdleIRq and LoAlert
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
MInfo.nBitsReceived = -(ReadRC(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
MInfo.nBitsReceived = -(ReadRC(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
// processing time counter
// 6.4 us resolution - max 420 ms
WriteRC(RegInterruptEn,irqEn | 0x80); //necessary interrupts are enabled // count up from 1
//中断开放
//这时中断打开,首先去处理要发送的数据,放到FIFO
Delay(100); //////////////////////////////////add
WriteRC(RegCommand,cmd); //start command
tmpStatus=ReadRC(RegFIFOLength); //此未用
_nop_();
// wait for commmand completion
// a command is completed, if the corresponding interrupt occurs
// or a timeout is signaled
i=0;
//SendEnter();
while (!(MInfo.irqSource & waitFor)) //如果Idle为中断,则既是命令未执行完毕,在此循环,直到执行完毕
{
i++;
//printf("%d",i);
//printf("\n");
if(i>5000)
{
Mf500PcdConfig();
return 1;
}
} // wait for cmd completion or timeout
//while (!(MInfo.irqSource & waitFor)); // wait for cmd completion or timeout
WriteRC(RegInterruptEn,0x7F); // disable all interrupts
WriteRC(RegInterruptRq,0x7F); // clear all interrupt requests
SetBitMask(RegControl,0x04); // stop timer now
WriteRC(RegCommand,PCD_IDLE); // reset command register
if (!(MInfo.irqSource & waitFor)) // reader has not terminated
{ // timer 3 expired
status = MI_ACCESSTIMEOUT;
}
else
status = MInfo.status; // set status
if (status == MI_OK) // no timeout error occured
{
if ((tmpStatus = (ReadRC(RegErrorFlag) & 0x17))) // error occured
{
if (tmpStatus & 0x01) // collision detected
{
// SendData("err a ");
MInfo.collPos = ReadRC(RegCollPos); // read collision position
status = MI_COLLERR;
}
else
{
MInfo.collPos = 0;
if (tmpStatus & 0x02) // parity error
{
// SendData("err b ");
status = MI_PARITYERR;
}
}
if (tmpStatus & 0x04) // framing error
{
// SendData("err c ");
status = MI_FRAMINGERR;
}
if (tmpStatus & 0x10) // FIFO overflow
{
FlushFIFO();
// SendData("err d ");
status = MI_OVFLERR;
}
if (tmpStatus & 0x08) // CRC error
{
// SendData("err e ");
status = MI_CRCERR;
}
////////////////////////////为什ok了还要置错误//////////////
// if (status == MI_OK)
// status = MI_NY_IMPLEMENTED; ////???????????????????????????????????!!!!!!!!!!!!!!
//////////////////////////////////////////////////////
//printf("\n erro is:%d",status); ////////////////////
//printf("\n");
// key error occures always, because of
// missing crypto 1 keys loaded
} //END EER
// 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 = ReadRC(RegSecondaryStatus) & 0x07;
if (lastBits)
MInfo.nBitsReceived += (MInfo.nBytesReceived-1)*8 + lastBits;
else
MInfo.nBitsReceived=(MInfo.nBytesReceived)*8+MInfo.nBitsReceived;
}
}
else
{
MInfo.collPos = 0x00;
}
}
// reset interface variables for ISR
haveset=0;
return status;
}
void int2() interrupt 2 using 2
{
static unsigned char irqBits;
static unsigned char irqMask;
// static unsigned char oldPageSelect;
static unsigned char nbytes;
static unsigned char cnt;
EA=0;
if (haveset)//MpIsrInfo && MpIsrOut && MpIsrIn) // transfer pointers have to be set
// correctly
{
//oldPageSelect = ReadRC(RegPage); // save old page select
// Attention: ReadRC cannnot be
// used because of the internal
// write sequence to the page
// reg
//WriteRC(RegPage,0x80); // select page 0 for ISR
while( (ReadRC(RegPrimaryStatus) & 0x08)) // loop while IRQ pending
{
irqMask = ReadRC(RegInterruptEn); // read enabled interrupts
// read pending interrupts
irqBits = ReadRC(RegInterruptRq) & irqMask; //算出中断的位数
MInfo.irqSource |= irqBits; //save pending interrupts
/******************************///FIFO为空时执行的中断
if (irqBits & 0x01) // LoAlert
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -