📄 fm1702.c
字号:
#include "config.h"
#include "FM1702.h"
extern uchar UID[5];
extern uchar buf[16];
extern uchar TagType;
extern uchar KeyA[6];
extern unsigned char ReadSingle(uchar address);
extern void WriteSingle(uchar address, uchar data);
uchar FM1715_SPI_SEL(void)
{
uint i;
uchar tmp; //=0xff;
for(i=0; i<RF_TimeOut; i++)
{
asm("wdr"); //reset watchdog
tmp = ReadSingle(Command);
if(tmp == 0x00)
{
WriteSingle(Page0, 0x80);
for(i=0; i<0xfff; i++) asm("nop");
tmp = 0x3f;
//while(tmp!=0)
while((tmp&0x3f)==0x00)
{
tmp = ReadSingle(Command);
//tmp &= 0x3f; //clear the first two bits
}
WriteSingle(Page0, 0x00);
for(i=0; i<0xfff; i++) asm("nop");
return 0;
}
}
return 1;
}
/***********************************************************/
//temp1=0x03: 上海标准TOKEN卡
//temp1=0x04: MIFARE标准8K
//temp1=0x05: MIFRAR标准TOKEN卡
//temp1=0x53: 上海标准8K
/***********************************************************/
uchar Judge_Req(void)
{
//uchar tmp1, tmp2;
//tmp1 = buf[0];
//tmp2 = *(buffer+1);
//if(((tmp1==0x03)||(tmp1==0x04)||(tmp1==0x05)||(tmp1==0x53))&&(tmp2==0x00))
if(buf[0]==0x04)
{
return 0;
}
return 1;
}
void Set_BitFraming(uchar row, uchar col)
{
switch(row)
{
case 0:
buf[1] = 0x20;
break;
case 1:
buf[1] = 0x30;
break;
case 2:
buf[1] = 0x40;
break;
case 3:
buf[1] = 0x50;
break;
case 4:
buf[1] = 0x60;
}
switch(col)
{
case 0:
WriteSingle(BitFraming, 0x00);
break;
case 1:
WriteSingle(BitFraming, 0x11);
buf[1] = buf[1] | 0x01;
break;
case 2:
WriteSingle(BitFraming, 0x22);
buf[1] = buf[1] | 0x02;
break;
case 3:
WriteSingle(BitFraming, 0x33);
buf[1] = buf[1] | 0x03;
break;
case 4:
WriteSingle(BitFraming, 0x44);
buf[1] = buf[1] | 0x04;
break;
case 5:
WriteSingle(BitFraming, 0x55);
buf[1] = buf[1] | 0x05;
break;
case 6:
WriteSingle(BitFraming, 0x66);
buf[1] = buf[1] | 0x06;
break;
case 7:
WriteSingle(BitFraming, 0x77);
buf[1] = buf[1] | 0x07;
break;
default:
break;
}
}
uchar CheckUID(void)
{
uchar tmp, i;
tmp = 0x00;
for(i=0; i<5; i++) tmp ^= UID[i];
return tmp;
//if(tmp == 0x00) return 0;
//return 1;
}
void SaveUID(uchar row, uchar col, uchar length)
{
uchar i, tmp, tmp1;
//if((row == 0x00)&&(col == 0x00))
if((row|col) == 0x00)
{
for(i=0; i<length; i++)
{
UID[i] = buf[i];
}
}
else
{
tmp = buf[0];
tmp1 = UID[row-1];
switch(col)
{
case 0:
tmp1 = 0;
row = row + 1;
break;
case 1:
tmp = tmp &0xfe;
tmp1 = tmp1 & 0x01;
break;
case 2:
tmp = tmp & 0xfc;
tmp1 = tmp1 & 0x0c;
break;
case 3:
tmp = tmp & 0xf8;
tmp1 = tmp1 & 0x07;
break;
case 4:
tmp = tmp & 0xf0;
tmp1 = tmp1 & 0x0f;
break;
case 5:
tmp = tmp & 0xe0;
tmp1 = tmp1 & 0x1f;
break;
case 6:
tmp = tmp & 0xc0;
tmp1 = tmp1 & 0x3f;
break;
case 7:
tmp = tmp & 0x80;
tmp1 = tmp1 & 0x7f;
break;
default:
break;
}
buf[0] = tmp;
//UID[row-1] = tmp1|tmp;
UID[0] = tmp;
for(i=0; i<length; i++)
{
UID[row-1+i] = buf[i];
}
}
}
void FM1702SLInit(void)
{
uchar tmp=0xff;
uint i;
MF_RST;
for(i=0;i<10000;i++)//about 10ms
{
//vDelay(2000);
//asm("nop");
asm("wdr"); //reset watchdog
}
nMF_RST;
for(i=0;i<10000;i++)//about 10ms
{
//vDelay(200);
//asm("nop");
asm("wdr"); //reset watchdog
}
tmp = 0xff;
while(tmp!=0)
{
tmp=ReadSingle(Command);
asm("wdr"); //reset watchdog
}
FM1715_SPI_SEL();
//tmp = 0xff;
//while(tmp!=0)
//{
// tmp = ReadSingle(Command);
//}
WriteSingle(TimerClock, 0x0b); //151us/per
WriteSingle(TimerControl, 0x02); //发送结束开定时器,接收开始关定时器
WriteSingle(TimerReload, 0x42); //10ms定时
WriteSingle(InterruptEn, 0x7f); //关闭所有中断
WriteSingle(InterruptRq, 0x7f);
WriteSingle(TxControl, 0x5b); //开启TX1, TX2
//tmp=ReadSingle(TimerClock);
//tmp=ReadSingle(TimerControl);
//tmp=ReadSingle(TimerReload);
//tmp=ReadSingle(InterruptEn);
}
uchar ReadFIFO(uchar *pbuf)
{
uchar addr, data, i, Length;
Length = ReadSingle(FIFO_Length);
if(Length == 0x00) return 1;
if(Length>24) Length = 24;
for(i=0; i<Length; i++)
{
*(pbuf+i) = FIFOData;
}
*(pbuf+Length) = 0x00; //set the last byte to 0
addr = (0x80|FIFOData); //set the MSB to 1, 1st byte is address
nSpiSs;
for(i=0; i<8; i++)
{
if(addr&0x80) SpiDataOut;
else nSpiDataOut;
asm("nop"); //__asm__ volatile("nop");
SpiSclk;
asm("nop"); //__asm__ volatile("nop");
nSpiSclk;
//addr = addr << 1;
//__asm__ volatile("lsl %0":"=r"(addr):"0"(addr));
asm("lsl %addr");
}
//SpiSs;
while(Length > 0)
{
//data = 0;
addr = *pbuf;
//nSpiSs;
for(i=0; i<8; i++)
{
if(addr&0x80) SpiDataOut;
else nSpiDataOut;
addr = addr << 1;
SpiSclk;
if(RF_SPI_MISO)
{
data |= 0x01;
}
else
{
data &= (~(0x01));
}
if(i != 7)
{
//data = data<<1;
//__asm__ volatile("lsl %0":"=r"(data):"0"(data));
asm("lsl %data");
}
nSpiSclk;
}
*pbuf = data;
pbuf++;
Length--;
}
SpiSs;
return 0;
}
void WriteFIFO(uchar *pbuf, uchar lenght)
{
uchar tmp, i;
tmp = FIFOData&0x7f; //set the MSB to 0, 1st byte is address
nSpiSs;
for(i=0; i<8; i++)
{
if(tmp&0x80) SpiDataOut;
else nSpiDataOut;
asm("nop");
SpiSclk;
asm("nop");
nSpiSclk;
asm("lsl %tmp");
}
//SpiSs;
while(lenght > 0)
{
tmp = *pbuf; //send command and data
//nSpiSs;
for(i=0; i<8; i++)
{
if(tmp&0x80) SpiDataOut;
else nSpiDataOut;
asm("nop");
SpiSclk;
asm("nop");
nSpiSclk;
//tmp = tmp << 1;
asm("lsl %tmp");
}
pbuf++;
lenght--;
}
SpiSs;
}
uchar ClearFIFO(void)
{
uchar tmp;
uint i;
tmp = ReadSingle(Control);
tmp = tmp|0x01;
WriteSingle(Control, tmp);
for(i=0; i<RF_TimeOut; i++)
{
tmp = ReadSingle(FIFO_Length);
if(tmp == 0x00)
{
return 0;
}
asm("wdr"); //reset watchdog
//return 1;
//return ReadSingle(FIFO_Length);
}
return 1;
}
uchar Command_Send(uchar count, uchar Comm_Set)
{
uint i, j;
uchar tmp;
WriteSingle(Command, 0x00);
tmp = ClearFIFO();
if(tmp == 1) return 1;
WriteFIFO(buf, count);
WriteSingle(Command, Comm_Set);
for(i=0; i<0x100; i++)
{
for(j=0; j<20; j++)
{
asm("nop");
}
tmp = ReadSingle(Command);
if(tmp == 0x00) return 0;
for(j=0; j<20; j++)
{
asm("nop");
}
tmp = ReadSingle(InterruptRq);
if((tmp&0x80)==0x80) return 0;
}
return 1;
}
uchar MIF_Halt(void)
{
//uchar tmp;
//uchar i;
WriteSingle(CRCPresetLSB, 0x63);
WriteSingle(CWConductance, 0x3f);
WriteSingle(ChannelRedundancy, 0x03);
buf[1] = RF_CMD_HALT;
buf[2] = 0x00;
//tmp = Command_Send(2, buf, Transmit);
return Command_Send(2, Transmit);
/*
if(tmp == 0)
{
//for(i=0; i<0x50; i++) ;
return FM1715_OK;
}
else
{
tmp = ReadSingle(ErrorFlag);
if((tmp&0x02) == 0x02)
{
return(FM1715_PARITYERR);
}
else if((tmp&0x04) == 0x04)
{
return(FM1715_FRAMINGERR);
}
return(FM1715_NOTAGERR);
}*/
}
/*
uchar Load_keyE2_CPY(uchar Secnr, uchar Mode)
{
uchar tmp;
uchar msb = 0;
uchar lsb = 0;
tmp = Secnr*12;
if(Mode == 0x00)
{
if(tmp>=0x80)
{
lsb = tmp*0x80;
msb = 0x01;
}
else
{
msb = 0x00;
lsb = tmp + 0x80;
}
}
else
{
msb = 0x01;
lsb = tmp + 0x80;
}
buf[0] = lsb;
buf[1] = msb;
tmp = Command_Send(2, buf, LoadKeyE2);
tmp = ErrorFlag&0x40;
if(tmp == 0x40)
{
return 1;
}
return 0;
}
*/
uchar Load_Key(void)
{
uchar i, tmp;
uchar *ptr;
ptr = buf;
for(i=0; i<6; i++)
{
tmp = (KeyA[i]&0xf0);
tmp |= (tmp>>4);
tmp ^= 0xf0;
*(ptr++) = tmp;
tmp = (KeyA[i]&0x0f);
tmp |= (tmp<<4);
tmp ^= 0xf0;
*(ptr++) = tmp;
}
WriteSingle(Command, 0x00);
tmp = ClearFIFO();
WriteFIFO(buf, 12);
WriteSingle(Command, LoadKey);
//for(i=0; i<10000; i++){};
tmp = ReadSingle(ErrorFlag);
if((tmp&0x40) == 0x40) return 1; //load key error flag set
return 0;
}
uchar Request(uchar mode)
{
uchar tmp;
WriteSingle(CRCPresetLSB, 0x63);
WriteSingle(CWConductance, 0x3f);
WriteSingle(BitFraming, 0x07); //send 7bit data
WriteSingle(ChannelRedundancy, 0x03); //without CRC
tmp = ReadSingle(Control);
tmp = tmp&0xf7; //clear CRYPTO1 bit
WriteSingle(Control, tmp);
buf[0] = mode;
tmp = Command_Send(1, Transceive);
if(tmp == 1)
{
return FM1715_NOTAGERR;
}
tmp = ReadFIFO(buf); //read response data
if(tmp == 0x00)
{
tmp = Judge_Req();
if(tmp == 0)
{
//TagType = buf[0]; //[0] = buf[0];
return FM1715_OK;
}
}
return FM1715_REQERR;
}
uchar AntiColl(void)
{
uchar tmp;
uchar i;
uchar row, col;
uchar pre_row;
row = 0;
col = 0;
pre_row = 0;
WriteSingle(CRCPresetLSB, 0x63);
WriteSingle(CWConductance, 0x3f);
WriteSingle(ChannelRedundancy, 0x03);
buf[0] = RF_CMD_ANTICOL;
buf[1] = 0x20;
tmp = Command_Send(2, Transceive);
while(1)
{
if(tmp == 1)
{
return(FM1715_NOTAGERR);
}
tmp = ReadSingle(FIFO_Length);
if(tmp == 0x00)
{
return(FM1715_BYTECOUNTERR);
}
ReadFIFO(buf);
SaveUID(row, col, tmp);
tmp = ReadSingle(ErrorFlag);
tmp = tmp&0x01;
if(tmp == 0x00)
{
tmp = CheckUID();
if(tmp == 1)
{
return(FM1715_SERNRERR);
}
return(FM1715_OK);
}
else
{
/*
tmp = ReadSingle(CollPos);
row = tmp/8;
col = tmp%8;
buf[1] = RF_CMD_ANTICOL;
Set_BitFraming(row+pre_row, col);
pre_row = pre_row + row;
for(i=0; i<pre_row+1; i++)
{
buf[i+3] = UID[i];
}
if(col != 0x00)
{
row = pre_row + 1;
}
else
{
row = pre_row;
}
tmp = Command_Send(row+3, Transceive);
*/
return 1;
}
asm("wdr"); //reset watchdog
}
return 1;
}
uchar Select_Card(void)
{
uchar tmp, i;
WriteSingle(CRCPresetLSB, 0x63);
WriteSingle(CWConductance, 0x3f);
buf[0] = RF_CMD_SELECT;
buf[1] = 0x70;
for(i=0; i<5; i++)
{
buf[i+2] = UID[i];
}
WriteSingle(ChannelRedundancy, 0x0f);
tmp = Command_Send(7, Transceive);
if(tmp == 1)
{
return(FM1715_NOTAGERR);
}
else
{
tmp = ReadSingle(ErrorFlag);
//if((tmp&0x02)==0x02) return(FM1715_PARITYERR);
//if((tmp&0x04)==0x04) return(FM1715_FRAMINGERR);
//if((tmp&0x08)==0x08) return(FM1715_CRCERR);
if((tmp&0x0e) != 0) return tmp;
tmp = ReadSingle(FIFO_Length);
if(tmp!=1) return(FM1715_BYTECOUNTERR);
ReadFIFO(buf);
tmp = *buf;
if((tmp==0x08)||(tmp==0x88)||(tmp==0x53)) return(FM1715_OK);
//if(tmp==0x88) return(FM1715_OK);
return(FM1715_SELERR);
}
}
//***************************************************************
//SecNR: sector number
//mode: mode selection, KeyA selection: 0, KeyB selection: 1
//***************************************************************
uchar Authentication(uchar SecNR) //, uchar mode)
{
uchar i;
uchar tmp;
WriteSingle(CRCPresetLSB, 0x63);
WriteSingle(CWConductance, 0x3f);
tmp = ReadSingle(Control);
tmp = tmp&0xf7;
WriteSingle(Control, tmp);
//if(mode == 1) buf[0] = RF_CMD_AUTHEN_LB;
//else buf[0] = RF_CMD_AUTHEN_LA;
buf[0] = RF_CMD_AUTHEN_LA;
buf[1] = SecNR*4+3;
for(i=0; i<4; i++)
{
buf[2+i] = UID[i];
}
WriteSingle(ChannelRedundancy, 0x0f);
tmp = Command_Send(6, Authent1);
if(tmp == 1) return FM1715_NOTAGERR;
tmp = ReadSingle(ErrorFlag);
if((tmp&0x0e) != 0) return tmp;
//if((tmp&0x02)==0x02) return(FM1715_PARITYERR);
//if((tmp&0x04)==0x04) return(FM1715_FRAMINGERR);
//if((tmp&0x08)==0x08) return(FM1715_CRCERR);
tmp = Command_Send(0, Authent2);
if(tmp == 1) return FM1715_NOTAGERR;
tmp = ReadSingle(ErrorFlag);
if((tmp&0x0e) != 0) return tmp;
//if((tmp&0x02)==0x02) return(FM1715_PARITYERR);
//if((tmp&0x04)==0x04) return(FM1715_FRAMINGERR);
//if((tmp&0x08)==0x08) return(FM1715_CRCERR);
tmp = ReadSingle(Control);
if((tmp&0x08)==0x08) return (FM1715_OK);
return (FM1715_AUTHERR);
}
uchar MIF_READ(uchar Block_Addr)
{
uchar tmp;
WriteSingle(CRCPresetLSB, 0x63);
WriteSingle(CWConductance, 0x3f);
WriteSingle(ChannelRedundancy, 0x0f);
buf[0] = RF_CMD_READ;
buf[1] = Block_Addr;
tmp = Command_Send(2, Transceive);
if(tmp == 1) return FM1715_NOTAGERR;
tmp = ReadSingle(ErrorFlag);
if((tmp&0x0e) != 0) return tmp;
//if((tmp&0x02)==0x02) return(FM1715_PARITYERR);
//if((tmp&0x04)==0x04) return(FM1715_FRAMINGERR);
//if((tmp&0x08)==0x08) return(FM1715_CRCERR);
return ReadFIFO(buf);
}
/*
uchar MIF_WRITE(uchar Block_Addr)
{
uchar tmp;
uchar *F_buff;
WriteSingle(CRCPresetLSB, 0x63);
WriteSingle(CWConductance, 0x3f);
F_buff = buf + 0x10;
WriteSingle(ChannelRedundancy, 0x07);
*F_buff = RF_CMD_WRITE;
*(F_buff+1) = Block_Addr;
tmp = Command_Send(2, Transceive);
if(tmp == 1) return(FM1715_NOTAGERR);
tmp = ReadSingle(FIFO_Length);
if(tmp == 0x00) return(FM1715_BYTECOUNTERR);
ReadFIFO(F_buff);
tmp = *F_buff;
switch(tmp)
{
case 0x00:
return(FM1715_NOTAGERR);
case 0x04:
return(FM1715_EMPTY);
case 0x0a:
break;
case 0x01:
return(FM1715_CRCERR);
case 0x05:
return(FM1715_PARITYERR);
default:
return(FM1715_WRITEERR);
}
tmp = Command_Send(16, Transceive);
if(tmp == 0) return(FM1715_OK);
else
{
tmp = ErrorFlag;
if((tmp&0x02) == 0x02) return(FM1715_PARITYERR);
if((tmp&0x04)==0x04) return(FM1715_FRAMINGERR);
if((tmp&0x08)==0x08) return(FM1715_CRCERR);
else return(FM1715_WRITEERR);
}
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -