📄 rc500.c
字号:
// memmove(temp_buf,RECEIVEBUFFER+5,1); //搬移1个16进制数
temp_buf[0]=RECEIVEBUFFER[5];
temp_buf[1]=0;
temp_buf[2]=0;
temp_buf[3]=0;
status=Mf500PiccValue(0xc1,block_num,temp_buf,block_num); //增值操作
if(status==0)
SendData("Inc value ok");
else
SendData("Inc value not ok");
break;
case 0x44: //idle
status=Mf500PiccHalt();
if(status==0)
SendData("Close ok");
else
SendData("Close lose");
break;
default:
SendData("erro command");
break;
}//run command
}////接收成功
}//while(1)
}//end main()
/****************************************************************************
* *
* Function: Mf500PcdConfig *
* *
* Input: *
* Output: STATE *
* *
****************************************************************************/
char Mf500PcdConfig(void)
{
char idata status = MI_RESETERR;
unsigned int idata RstLoopCnt = 0;
unsigned int idata CmdWaitCnt = 0;
// wait until reset command recognized
do
{
Delay(100); // wait
PReset=1; // reset RC500
Delay(300); // wait
PReset=0; // clear reset pin
Delay(300); // wait
}
while (ReadRC(RegPage) != 0x80);
do
{
WriteRC(RegPage,0x0); // Dummy access in order to determine the bus
}while(ReadRC(RegCommand) != 0x00); // configuration
// necessary read access
// after first write access, the returned value
// should be zero ==> interface recognized
if (ReadRC(RegCommand) != 0x00)
{
status = MI_INTERFACEERR;
}
else
{
status = 0;
}
if(status==0)
{
// loade2();
XBYTE[RegClockQControl]=0x0;
XBYTE[RegClockQControl]=0x40;
Delay(24);// wait approximately 100 us - calibration in progress
ClearBitMask(RegClockQControl,0x40); // clear bit ClkQCalib for
XBYTE[RegBitPhase]=0xAd;
XBYTE[RegRxThreshold]=0xFF;
XBYTE[RegRxControl2]=01;
XBYTE[RegFIFOLevel]=0x1A; // initialize to 26d
XBYTE[RegTimerControl]=0x02; // TStopRxEnd=0,TStopRxBeg=0,当数据发送结束时定时器自动启动
XBYTE[RegIRqPinConfig]=0x3; // interrupt active low enable管脚irq上的信号与位irq状态相反,标准cmos输出
//XBYTE[RegRxWait]=0x02; //////RxWait有默认值
status=PcdRfReset(1); // Rf - reset and enable output driver
}
return status;
}
/****************************************************************************
Request 指令将通知MCM在天线有效的工作范围(距离)内寻找MIFARE 1卡片。如果有
MIFARE 1卡片存在,这一指令将分别与MIFARE 1进行通信,读取MIFARE 1卡片上的卡片
类型号TAGTYPE(2个字节),由MCM传递给MCU,进行识别处理。
程序员可以根据TAGTYPE来区别卡片的不同类型。
对于MIFARE 1卡片来说,返回卡片的TAGTYPE(2个字节)可能为0004h。
* Function: Mf500PiccRequest *
* Input: req_code *
* Output: TagType *
* *
****************************************************************************/
char Mf500PiccRequest(unsigned char req_code,
unsigned char *atq)
{
char status = MI_OK;
char i;
PcdSetTmo(2);
WriteRC(RegChannelRedundancy,0x03); // RxCRC and TxCRC disable, parity enable
ClearBitMask(RegControl,0x08); // disable crypto 1 unit
WriteRC(RegBitFraming,0x07); // set TxLastBits to 7
ResetInfo();
//AUXR=0;
MSndBuffer[0] = req_code;
MInfo.nBytesToSend = 1;
status = PcdSingleResponseCmd(PCD_TRANSCEIVE);
if (status) // error occured
{
atq[0] = 0;
}
else
{
if (MInfo.nBitsReceived != 16) // 2 bytes expected
{
atq[0] = 0;
status = MI_BITCOUNTERR;
}
else
{
status = MI_OK;
for(i=0;i<2;i++) atq[i]=MRcvBuffer[i];
}
}
return status;
}
/****************************************************************************
*在一个成功的AntiCollision指令之后,或在任何时候当程序员想实际地与已知序列号
卡片进行通信时,必须使用Select指令,以建立与所选卡的通信。为了允许在Select指令
以后对卡片能进行Read/Write等指令的操作,Select指令是很重要的,必须首先被使用
被选择的卡片将给出其自己的存储器容量---已编码的一个BYTE(字节) *
* Function: Mf500PiccSelect *
* *
* Input: SNR 卡号 *
* Output: Size *
* *
****************************************************************************/
char Mf500PiccSelect(unsigned char *snr,unsigned char *sak)
{
return Mf500PiccCascSelect(0x93,snr,sak); // first cascade level
}
char Mf500PiccCascSelect(unsigned char select_code,
unsigned char *snr,
unsigned char *sak)
{
char status = MI_OK;
char i;
PcdSetTmo(106);
WriteRC(RegChannelRedundancy,0x0F); // RxCRC,TxCRC, Parity enable
ClearBitMask(RegControl,0x08); // disable crypto 1 unit
ResetInfo();
MSndBuffer[0] = select_code;
MSndBuffer[1] = 0x70; // number of bytes send
for(i=0;i<4;i++) MSndBuffer[2+i]=snr[i];
//memcpy(MSndBuffer + 2,snr,4);
MSndBuffer[6] = MSndBuffer[2]
^ MSndBuffer[3]
^ MSndBuffer[4]
^ MSndBuffer[5];
MInfo.nBytesToSend = 7;
status = PcdSingleResponseCmd(PCD_TRANSCEIVE);
sak[0] = 0;
if (status == MI_OK) // no timeout occured
{
if (MInfo.nBitsReceived != 8) // last byte is not complete
{
status = MI_BITCOUNTERR;
}
else
{
sak[0] = MRcvBuffer[0];
memcpy(MLastSelectedSnr,snr,4);
}
}
return status;
}
/****************************************************************************
*如果有多于一张的Mifare 1卡片在MCM之天线的有效的工作范围(距离)内 ,必须使用
AntiCollision指令,使MCM能够在这一叠 Mifare 1卡片中选择个别的一张卡片。
*
* Function: Mf500PiccAnticoll//防碰撞函数 *
* *
* Input: Bcnt, SNR *
* Output: SNR *
* *
****************************************************************************/
char Mf500PiccAnticoll (unsigned char bcnt,
unsigned char *snr)
{
return Mf500PiccCascAnticoll(0x93,bcnt,snr); // first cascade level
}
char Mf500PiccCascAnticoll (unsigned char select_code,
unsigned char bcnt,
unsigned char *snr)
{
char status = MI_OK;
char snr_in[4]; // copy of the input parameter snr
char nbytes = 0; // how many bytes received
char nbits = 0; // how many bits received
char complete = 0; // complete snr recived
char i = 0;
char byteOffset = 0;
unsigned char snr_crc; // check byte calculation
unsigned char snr_check;
unsigned char dummyShift1; // dummy byte for snr shift
unsigned char dummyShift2; // dummy byte for snr shift
PcdSetTmo(2);
memcpy(snr_in,snr,4);
WriteRC(RegDecoderControl,0x28); // ZeroAfterColl aktivieren
ClearBitMask(RegControl,0x08); // disable crypto 1 unit
complete=0;
while (!complete && (status == MI_OK) )
{
ResetInfo();
WriteRC(RegChannelRedundancy,0x03); // RxCRC and TxCRC disable, parity enable
nbits = bcnt % 8;
if (nbits)
{
WriteRC(RegBitFraming,nbits << 4 | nbits); // TxLastBits/RxAlign auf nb_bi
nbytes = bcnt / 8 + 1;
if (nbits == 7 )
{
MInfo.cmd = PICC_ANTICOLL1; // pass command flag to ISR
WriteRC(RegBitFraming,nbits); // reset RxAlign to zero
}
}
else
{
nbytes = bcnt / 8;
}
MSndBuffer[0] = select_code;
MSndBuffer[1] = 0x20 + ((bcnt/8) << 4) + nbits; //number of bytes send
for (i = 0; i < nbytes; i++) // Sende Buffer beschreiben
{
MSndBuffer[i + 2] = snr_in[i];
}
MInfo.nBytesToSend = 2 + nbytes;
status = PcdSingleResponseCmd(PCD_TRANSCEIVE);
// in order to solve an inconsistancy in the anticollision sequence
// (will be solved soon), the case of 7 bits has to be treated in a
// separate way
if (nbits == 7)
{
// reorder received bits
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; // subtract received parity bits
// recalculation of collision position
if ( MInfo.collPos ) MInfo.collPos += 7 - (MInfo.collPos + 6) / 9;
}
if ( status == MI_OK || status == MI_COLLERR) // no other occured
{
// R e s p o n s e P r o c e s s i n g
if ( MInfo.nBitsReceived != 40) // not 5 bytes answered
{
status = MI_BITCOUNTERR;
}
else
{
byteOffset = 0;
if ( nbits != 0 ) // last byte was not complete
{
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 ) // no error and no collision
{
// SerCh check
snr_crc = snr_in[0] ^ snr_in[1] ^ snr_in[2] ^ snr_in[3];
snr_check = MRcvBuffer[4];
if (snr_crc != snr_check)
{
status = MI_SERNRERR;
}
else
{
complete = 1;
}
}
else // collision occured
{
bcnt = bcnt + MInfo.collPos - nbits;
status = MI_OK;
}
}
}
}
if (status == MI_OK)
{
for(i=0;i<4;i++)
{
// csn[i]=MRcvBuffer[i];
snr[i]=MRcvBuffer[i];
}
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -