⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fm1702.c

📁 该代码是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 + -