0111,1111:禁中断请 求*/
WriteIO(RegCommand,PCD_IDLE);/*(01H)命令代号均写入此处相当于单片机的指令寄存器PC:进入待命 态*/
FlushFIFO();/*清缓冲区标志?这样FIFO区就可供单片机或RC500状态机使用*/
MpIsrInfo=info;/*?*/
MpIsrOut=rcv;/*接收数据缓冲区*/
info->irqSource=0x00;/*->:存储结构或联合单元?右结合?*/ switch(cmd)
{/*根据输入的命令分支*/
casePCD_IDLE:/*是IDLE命令?00H?*/ irqEn=0x00; waitFor=0x00; break;
casePCD_WRITEE2:/*是写EEROM命令?01H?*/ irqEn=0x11; waitFor=0x10; break;
casePCD_READE2:/*是读EEROM命令?03H?*/ irqEn=0x07; .waitFor=0x04; break;
case CD_LOADCONFIG:/*是载入配置命令?07H?*/
case PCD_LOADKEYE2:/*是从EEROM载入密钥命令?0BH?*/ case CD_AUTHENT1:/*是执行认证1命令?0CH?*/ irqEn=0x05; waitFor=0x04; break;
casePCD_CALCCRC:/*是激活CRC命令?12H?*/ irqEn=0x11; waitFor=0x10; break;
casePCD_AUTHENT2:/*是执行认证2命令?14H?*/ irqEn=0x04; waitFor=0x04; break;
casePCD_RECEIVE:/*是激活接收器命令?16H?*/
info->nBitsReceived=-(ReadIO(RegBitFraming)>>4); irqEn=0x06; waitFor=0x04; break;
Case PCD_LOADKEY:/*是从FIFO中载入密钥命令?19H?*/
irqEn=0x05; waitFor=0x04; break;
casePCD_TRANSMIT:/*是将FIFO数据发送到卡片命令?1AH?*/ irqEn=0x05; waitFor=0x04; break;
case PCD_TRANSCEIVE:/*是先发送然后立即接收命令?1EH?*/ 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--)));/*错误发生情况1?*/
WriteIO(RegInterruptEn,0x7F);/*定时器计完?禁中断系统*/ WriteIO(RegInterruptRq,0x7F);
SetBitMask(RegControl,0x04);/*这一位设置作用是立即结束中断计时*/ WriteIO(RegCommand,PCD_IDLE);/*进入IDLE态*/
if(!(MpIsrInfo->irqSource&waitFor))/*错误发生情况2*/ {
status=MI_ACCESSTIMEOUT;/*在规定的时间内没有完成任务*/ }
else/*错误发生情况3*/ {
status=MpIsrInfo->status; }
if(status==MI_OK)/*命令执行成功*/ {
if(tmpStatus=(ReadIO(RegErrorFlag)&0x17))/*取出错误状态寄存器内容*/ {
if(tmpStatus&0x01)/*取出比特碰撞位?是否为1?1?有碰撞?*/ {
info->collPos=ReadIO(RegCollPos);/*得到碰撞的具体位置*/ status=MI_COLLERR;/*有碰撞*/
} else {
info->collPos=0;/*无碰撞*/ if(tmpStatus&0x02) {
status=MI_PARITYERR;/*1?奇偶校验错*/ } }
if(tmpStatus&0x04)/*取出帧检测位?是否为1?1?帧头错SOF?*/ {
status=MI_FRAMINGERR;/*1?帧头错SOF*/ }
if(tmpStatus&0x10)/*取出FIFO状态位?是否为1*/ {
FlushFIFO();/*清缓冲区*/
status=MI_OVFLERR;/*1?FIFO满*/ }
if(tmpStatus&0x08)/*取出crc校验位?是否为1*/ {
status=MI_CRCERR;/*1?CRC校验错*/ }
if(status==MI_OK)
status=MI_NY_IMPLEMENTED;//该命令不存在 }
if(cmd==PCD_TRANSCEIVE)/*如果是发接指令1*/ {
lastBits=ReadIO(RegSecondaryStatus)&0x07;/*取出最后三位*/ if(lastBits)/*最后三位为1-7?不全有效*/
info->nBitsReceived+=(info->nBytesReceived-1)*8+lastBits; else/*最后三位为0?全有效*/
info->nBitsReceived+=info->nBytesReceived*8; } } else {
info->collPos=0x00;/*无碰撞*/ } }
MpIsrInfo=0; MpIsrOut=0; return status; }
////////////////////////////////////////////////////////////////////
///
//置RC500寄存器bit
///////////////////////////////////////////////////////////////////////
charSetBitMask(unsignedcharreg,unsignedcharmask) {/*相应的寄存器?REG)?相应的屏蔽位?MASK?*/ Char idatatmp=0x00; tmp=ReadIO(reg);
WriteIO(reg,tmp|mask);/*写入*/ return0x00; }
///////////////////////////////////////////////////////////////////////
//清RC500寄存器bit
///////////////////////////////////////////////////////////////////////
char ClearBitMask(unsignedcharreg,unsignedcharmask) {/*相应的寄存器?REG)?相应的屏蔽位?MASK?*/ charidatatmp=0x00; tmp=ReadIO(reg);
WriteIO(reg,tmp&~mask);/*写入*/ Return 0x00; }
///////////////////////////////////////////////////////////////////////
/*清缓冲区标志?这样RC500的FIFO取就可供单片机或RC500状态机使用*/ ///////////////////////////////////////////////////////////////////////
voidFlushFIFO(void) {
SetBitMask(RegControl,0x01);/*控制寄存器地址?09H------置1?FIFOFLUSH=1)*/ }
///////////////////////////////////////////////////////////////////////
//ValueformatoperationsforMifareStandardcardICs
/*改变MIFARE1卡内部EEROM的内容?单调增加?单调减少?数据检验操作?*/
///////////////////////////////////////////////////////////////////////
charM500PiccValue(unsignedchardd_mode, unsignedcharaddr, unsignedchar*value,
unsignedchartrans_addr)
{/*VALUE:连续写入的四字节指针?TRANS_ADDR:指向的改变后的数据要存入的地址*/
Char status=MI_OK;/*SATUS:置初值*/
/*DD_MODE:三种命令模式?ADDR:指向的要改变数据单元的地址*/ M500PcdSetTmo(1);/*初始化计时器--方式1*/ ResetInfo(MInfo);/*Minfo=INFO*/
SerBuffer[0]=dd_mode;/*93h,95h,97h三种命令模式*/
SerBuffer[1]=addr;/*ADDR:指向的要改变数据单元的地址*/ MInfo.nBytesToSend=2;/*要发送的字节数*/ status=M500PcdCmd(PCD_TRANSCEIVE, SerBuffer, &MInfo);
/*执行先送后接指令后返回STATUS*/
if(status!=MI_NOTAGERR)/*MI_NOTAGERR=没有卡在此场里*/ {/*有卡在此场里*/
if(MInfo.nBitsReceived!=4)/*收到的数据不是4比特*/ {
status=MI_BITCOUNTERR;/*置收到错误的比特数目标志位*/ }
else/*收到的数据是4比特*/ {
SerBuffer[0]&=0x0f;/*取出低四位*/ switch(SerBuffer[0]) {
case0x00:
status=MI_NOTAUTHERR;/*0000=置收到错误的比特数目标志位*/ break;
case0x0a:/*1010=置命令正确执行位*/ status=MI_OK; break;
case0x01:/*0001=置数据结构错误位*/ status=MI_VALERR; break; default:
status=MI_CODEERR;/*收到NACK,发送的数据出错?CRC,PARITY?*/ break; } } }
if(status==MI_OK)
{/*TRANSCEIVE命令执行成功*/
M500PcdSetTmo(3);/*初始化计时器--方式3*/ ResetInfo(MInfo);/*Minfo=INFO*/
memcpy(SerBuffer,value,4);/*将缓冲区里放入要改变的数据*/