📄 rc500.c
字号:
//文件包含
struct MfCmdInfo *MpIsrInfo = 0;
unsigned char *MpIsrOut = 0;
unsigned char *MpIsrIn = 0;
void delay()
{
nop();
clrwdt();
nop();
clrwdt();
}
void ISR_RC500(void)
{
unsigned char irqBits; //中断状态
unsigned char irqMask; //中断允许
unsigned char oldPageSelect; //原页号保存
unsigned char nbytes;
unsigned char cnt;
if (MpIsrInfo && MpIsrOut && MpIsrIn) // transfer pointers have to be set
{
oldPageSelect = GetRC500(RegPage); // save old page select
PutRC500(RegPage,0x80); // select page 0 for ISR
while ((GetRC500(RegPrimaryStatus) & 0x08)) // loop while IRQ pending
{
irqMask = GetRC500(RegInterruptEn); // read enabled interrupts
irqBits = GetRC500(RegInterruptRq) & irqMask;
MpIsrInfo->irqSource |= irqBits; // save pending interrupts
if (irqBits & 0x01) // LoAlert
{
//nbytes = MFIFOLength - ReadRawRC(RegFIFOLength);
nbytes = 0x40 - GetRC500(RegFIFOLength);
if ((MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent) <= nbytes)
{
nbytes = MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent;
PutRC500(RegInterruptEn,0x01); // disable LoAlert IRQ
}
for ( cnt = 0;cnt < nbytes;cnt++)
{
PutRC500(RegFIFOData,MpIsrOut[MpIsrInfo->nBytesSent]);
MpIsrInfo->nBytesSent++;
//dog=~dog;
}
PutRC500(RegInterruptRq,0x01); // reset IRQ bit
}
if (irqBits & 0x10) // TxIRQ
{
PutRC500(RegInterruptRq,0x10); // reset IRQ bit
PutRC500(RegInterruptEn,0x82); // enable HiAlert Irq for
// response
if (MpIsrInfo->cmd == PICC_ANTICOLL1) // if cmd is anticollision
{
PutRC500(RegChannelRedundancy,0x02); // RxCRC and TxCRC disable, parity disable
PutRC500(RegPage,0x00); // reset page address
}
}
if (irqBits & 0x0E) // HiAlert, Idle or RxIRQ
{
nbytes = GetRC500(RegFIFOLength);
for ( cnt = 0; cnt < nbytes; cnt++)
{
MpIsrIn[MpIsrInfo->nBytesReceived] = GetRC500(RegFIFOData);
MpIsrInfo->nBytesReceived++;
}
PutRC500(RegInterruptRq,0x0A & irqBits);
}
if (irqBits & 0x04) // Idle IRQ
{
PutRC500(RegInterruptEn,0x20); // disable Timer IRQ
PutRC500(RegInterruptRq,0x20); // disable Timer IRQ request
irqBits &= ~0x20; // clear Timer IRQ in local var
MpIsrInfo->irqSource &= ~0x20; // clear Timer IRQ in info var
PutRC500(RegInterruptRq,0x04); // reset IRQ bit
}
if (irqBits & 0x20) // timer IRQ
{
PutRC500(RegInterruptRq,0x20); // reset IRQ bit
MpIsrInfo->status = MI_NOTAGERR; // timeout error
}
}
PutRC500(RegPage,oldPageSelect | 0x80);
}
}
// 在一个页内向RC500寄存器送数据
// 因为地址线只有3条,此操作可寻址8个地址
void PutRC500(unsigned char address,unsigned char dat3)//ok
{
tris_data_port=tris_output;
data_port=address;
rc500_ale=1;
rc500_ale=0;
rc500_cs=0;
data_port=dat3;
rc500_wr=0;
delay();
rc500_wr=1;
rc500_cs=1;
}
// 在一个页内从RC500寄存器读数据
// 因为地址线只有3条,此操作可寻址8个地址
char GetRC500(unsigned char address)//ok
{
unsigned char temp_data;
tris_data_port=tris_output;
data_port=address;
rc500_ale=1;
rc500_ale=0;
rc500_cs=0;
tris_data_port=tris_input;
rc500_rd=0;
temp_data=data_port;
rc500_rd=1;
rc500_cs=1;
return temp_data;
}
// 写数据到RC500指定寄存器
void WriteRC(unsigned char Address, unsigned char value)//ok
{
PutRC500(0x00,GetRegPage(Address)); // select appropriate page
PutRC500(Address,value); // write value at the specified
}
// 从RC500指定寄存器读数据
char ReadRC(unsigned char Address)//ok
{
PutRC500(0x00,GetRegPage(Address)); // select appropriate page
return GetRC500(Address); // read value at the specified
}
char PcdReset(void)
{
unsigned int i,count01,count02;
char ret_status = MI_OK;
rc500_rst=0; // CLEAR_MRST();
for(i=0;i<16500;i++)
{clrwdt();}
rc500_rst=1; // SET_MRST();
for(i=0;i<1650;i++)
{clrwdt();}
rc500_rst = 0; // CLEAR_MRST();
rc500_cs = 0;
rc500_wr = 1;
rc500_rd = 1;
rc500_ale = 0;
count01=Timecount; // start_timeout(21);
count02=21;
// 检查是否复位成功,RegCommand&0x3F=0x3F?
while (((GetRC500(RegCommand) & 0x3F) != 0x3F) && (!(count02==0)))
{
count01--;
if (count01==0)
{
count01=Timecount;
count02--;
}
};
// 命令寄存器的Bit[0..5]不为全1,则认为复位不成功
while ((GetRC500(RegCommand) & 0x3F) && (!(count02==0)))
{
clrwdt();
count01--;
if (count01==0)
{
count01=Timecount;
count02--;
}
};
//stop_timeout();
if (count02==0)
{
ret_status = MI_RESETERR; // 芯片复位不正确
}
if (ret_status == MI_OK)
{
PutRC500(RegPage,0x80); // Dummy access in order to determine the bus
for(i=0;i<15;i++);
/* {
if (rc500_ale==0)
rc500_ale=1;
else
rc500_ale=0;
}*/
rc500_ale=0;
ret_status= GetRC500(RegCommand);
if (ret_status!= MI_OK)
{
ret_status = MI_INTERFACEERR;
}
else
{
PutRC500(RegPage,0x00); // sequence is ok
}
}
return ret_status;
}
// 设置RC500配置
char RC500Config(void)
{
unsigned char i;
// unsigned char temp;
char ret_status = MI_RESETERR;//-25
ret_status = PcdReset();
if (ret_status == MI_OK)//0
{
WriteRC(RegClockQControl,0x80); // RegClockQControl:0x1f
for(i=0;i<205;i++);
WriteRC(RegClockQControl,0xc0); //新加
for(i=0;i<105;i++);
ClearBitMask(RegClockQControl,0x40);
// WriteRC(RegCRCPresetLSB,0xAA);
// WriteRC(RegCRCPresetMSB,0xAA);
WriteRC(RegBitPhase,0xAD);
// WriteRC(RegRxWait,0x10);
WriteRC(RegRxThreshold,0xff);
WriteRC(RegRxControl1,0x73); //新加
WriteRC(RegRxControl2,0x81); //新改, 原为 0
WriteRC(RegFIFOLevel,0x4);
WriteRC(RegTimerControl,0x02);
PcdSetTmo(1); // short timeout
WriteRC(RegIRqPinConfig,0x3);
// WriteRC(RegCwConductance,0x39);
PcdRfReset(1);
}
return ret_status;
}
char RC500OutSelect(unsigned char type)
{
WriteRC(RegMfOutSelect,type&0x7);
return MI_OK;
}
char Mf500PiccRequest(unsigned char req_code,unsigned char *atq)
{
return Mf500PiccCommonRequest(req_code,atq);
}
char Mf500PiccCommonRequest(unsigned char req_code,unsigned char *atq) //ok
{
char ret_status = MI_OK;
PcdSetTmo(106);
// 关闭CRC校验,采用偶校验,RegChannelRedundancy是校验标志寄存器
WriteRC(RegChannelRedundancy,0x03); // RxCRC and TxCRC disable, parity enable
//
WriteRC(RegControl,0x08);
// ClearBitMask(RegControl,0x08); // disable crypto 1 unit
WriteRC(RegBitFraming,0x07); // set TxLastBits to 7
ResetInfo(MInfo);
MSndBuffer[0] = req_code;
MInfo.nBytesToSend = 1;
ret_status = PcdSingleResponseCmd(0x1e);
if (ret_status) // error occured
{
*atq = 0;
}
else
{
if (MInfo.nBitsReceived != 16) // 2 bytes expected
{
ret_status = MI_BITCOUNTERR;
}
else
{
ret_status = MI_OK;
memcpy(atq,MRcvBuffer,2);
}
}
return ret_status;
}
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)
{
signed char ret_status = MI_OK;
unsigned char snr_in[4]; // copy of the input parameter snr
unsigned char nbytes = 0; // how many bytes received
unsigned char nbits = 0; // how many bits received
unsigned char complete = 0; // complete snr recived
unsigned char i = 0;
unsigned 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
// if ((ret_status = Mf500PcdSetDefaultAttrib()) == MI_OK)
// {
PcdSetTmo(106);
memcpy(snr_in,snr,4);
WriteRC(RegDecoderControl,0x28); // ZeroAfterColl aktivieren
ClearBitMask(RegControl,0x08); // disable crypto 1 unit
complete=0;
while (!complete && (ret_status == MI_OK) )
{
ResetInfo(MInfo);
WriteRC(RegChannelRedundancy,0x03); // RxCRC and TxCRC disable, parity enable
nbits = bcnt % 8; // remaining number of bits
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;
ret_status = PcdSingleResponseCmd(0x1e);
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; // subtract received parity bits
if ( MInfo.collPos )
MInfo.collPos += 7 - (MInfo.collPos + 6) / 9;
}
if ( (ret_status == MI_OK) || (ret_status == MI_COLLERR)) // no other occured
{
if ( MInfo.nBitsReceived != (40 - bcnt) ) // not 5 bytes answered
{
ret_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 (ret_status != MI_COLLERR ) // no error and no collision
{
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)
{
ret_status = MI_SERNRERR;
}
else
{
complete = 1;
}
}
else // collision occured
{
bcnt = bcnt + MInfo.collPos - nbits;
ret_status = MI_OK;
}
}
}
// }
}
if (ret_status == MI_OK)
{
memcpy(snr,snr_in,4);
}
else
{
for(i=0;i<4;i++)
snr[i]=0;
memcpy(snr,"0000",4);
}
ClearBitMask(RegDecoderControl,0x20); // ZeroAfterColl disable
return ret_status;
}
//
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 ret_status = MI_OK;
// if ((ret_status = Mf500PcdSetDefaultAttrib()) == MI_OK)
// {
PcdSetTmo(106);
WriteRC(RegChannelRedundancy,0x0F); // RxCRC,TxCRC, Parity enable
ClearBitMask(RegControl,0x08); // disable crypto 1 unit
ResetInfo(MInfo);
MSndBuffer[0] = select_code;
MSndBuffer[1] = 0x70; // number of bytes send
memcpy(MSndBuffer + 2,snr,4);
MSndBuffer[6] = MSndBuffer[2]
^ MSndBuffer[3]
^ MSndBuffer[4]
^ MSndBuffer[5];
MInfo.nBytesToSend = 7;
ret_status = PcdSingleResponseCmd(0x1e);
*sak = 0;
if (ret_status == MI_OK) // no timeout occured
{
if (MInfo.nBitsReceived != 8) // last byte is not complete
{
ret_status = MI_BITCOUNTERR;
}
else
{
*sak = MRcvBuffer[0];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -