📄 fm1702.c
字号:
#include "head_macro.h"
#include "head_IO.h"
#include "head_buf.h"
#include "head_con.h"
#include <absacc.h>
#include <intrins.h>
#include "head_fm1702_Reg.h"
//uchar idata readdata[16];// _at_ 0x0040; //读写数据缓冲区
uchar idata value[4];// _at_ 0x0050; //增减的数值
uchar idata KeySet; //密码的类型
uchar idata tagtype[2];// _at_ 0x0096; //卡片标识字符card indentify character
//******************FM1715变量定义**********************************
//uchar idata PRO_SendBuf[16] _at_ 0x0080; //发送处理缓冲区16BYTE
uchar idata PRO_RecvBuf[16];// _at_ 0x0080; //接收处理缓冲区16BYTE
uchar idata buffer[24];// _at_ 0x0060; //fm1715 命令发送接收缓冲区
uchar idata UID[5];// _at_ 0x007a; //序列号User ID
uchar idata Secnr;// _at_ 0x0090; //扇区号
/*
***************************************************************/
/*名称: Judge_Req */
/*功能: 该函数实现对卡片复位应答信号的判断*/
/*输入: *buff, 指向应答数据的指针*/
/*输出:
temp1 =03 , 上海标准TOKEN卡
temp1 =04 , MIFARE标准8K
temp1 =05 , MIFARE 标准TOKEN卡
temp1 =53 ,上海标准8K卡
TRUE, 卡片应答信号正确*/
/* FALSE, 卡片应答信号错误*/
/***************************************************************
*/
uchar Judge_Req(uchar idata *buff)
{
uchar temp1, temp2;
temp1 = *buff;
temp2 = *(buff + 1);
if((temp1 == 0x02)||(temp1 == 0x03) || (temp1 == 0x04) || (temp1 == 0x05)
|| (temp1 == 0x53) && (temp2 == 0x00))
{
return TRUE;
}
return FALSE;
}
/*
******************************************
5.2.2 接收到的卡片UID号的判别
*名称: Check_UID
*功能: 该函数实现对收到的卡片的序列号的判断
*输入: N/A
*输出: TRUE: 序列号正确
FALSE : 序列号错误
******************************************
*/
uchar Check_UID(void)
{
uchar temp;
uchar i;
temp = 0x00;
for(i=0;i<5;i++)
{
temp=temp ^ UID[i];
}
if(temp == 0)
{
return TRUE;
}
return FALSE;
}
/*
保存卡片的UID号
***************************************************************
名称: Save_UID
功能: 该函数实现保存卡片收到的序列号
输入:
row: 产生冲突的行
col: 产生冲突的列
length: 接収到的UID数据长度
输出: N/A
/***************************************************************
*/
void Save_UID(uchar row,uchar col,uchar length)
{
uchar i;
uchar temp;
uchar temp1;
if((row == 0x00)&&(col==0x00))
{
for(i=0;i<length;i++)
{
UID[i]=buffer[i];
}
}
else
{
temp=buffer[0];
temp1=UID[row-1];
switch(col)
{
case 0:
temp1=0x00;
row=row+1;
break;
case 1:
temp=temp&0xFE;
temp1=temp1&0x01;
break;
case 2:
temp=temp&0xFC;
temp1=temp1&0x03;
break;
case 3:
temp=temp&0xF8;
temp1=temp1&0x07;
break;
case 4:
temp=temp&0xF0;
temp1=temp1&0x0F;
break;
case 5:
temp=temp&0xE0;
temp1=temp1&0x1F;
break;
case 6:
temp=temp&0xC0;
temp1=temp1&0x3F;
break;
case 7:
temp=temp&0x80;
temp1=temp1&0x7F;
break;
default:
break;
}
buffer[0]=temp;
UID[row-1]=temp1 | temp;
for(i=1;i<length;i++)
{
UID[row-1+i] =buffer[i];
}
}
}
/*
设置待发送数据的字节数
************************************************************
名称: Set_BitFraming
功能: 该函数设置待发送数据的字节数
输入:
row: 产生冲突的行
col: 产生冲突的列
输出: N/A
*************************************************************
*/
void Set_BitFraming(uchar row,uchar col)
{
switch(row)
{
case 0:
buffer[1]=0x20;
break;
case 1:
buffer[1]=0x30;
break;
case 2:
buffer[1]=0x40;
break;
case 3:
buffer[1]=0x50;
case 4:
buffer[1]=0x60;
break;
default:
break;
}
switch(col)
{
case 0:
BitFraming = 0x00;
break;
case 1:
BitFraming =0x11;
buffer[1]=(buffer[1]|0x01);
break;
case 2:
BitFraming =0x22;
buffer[1]=(buffer[1]|0x02);
break;
case 3:
BitFraming =0x33;
buffer[1]=(buffer[1]|0x03);
break;
case 4:
BitFraming =0x44;
buffer[1]=(buffer[1]|0x04);
break;
case 5:
BitFraming =0x55;
buffer[1]=(buffer[1]|0x05);
break;
case 6:
BitFraming =0x66;
buffer[1]=(buffer[1]|0x06);
break;
case 7:
BitFraming =0x77;
buffer[1]=(buffer[1]|0x07);
break;
default:
break;
}
}
/*
总线选择
**************************************************************
名称: FM1702_Bus_Sel
功能: 该函数实现对FM1702操作的总线方式
: (并行总线,SPI)选择
输入: N/A
输出:
TRUE, 总线选择成功
FALSE, 总线选择失败
***************************************************************
*/
uchar FM1702_Bus_Sel(void)
{
uint i;
Page_Sel= 0x80; //表示PageSelect的值做为寄存器地址A5,A4 和A3,低
//三位寄存器地址A2---A0 由外部地址线A2---A0 决定
for(i=0;i<RF_TimeOut;i++) //延时
{
if(Command == 0x00) //读命令执行结果, bit7为0表示接口检测结束
{
Page_Sel= 0x00; //探测完成。写0X00 切换到线性寻址方式
return TRUE;
}
}
return FALSE;
}
/****************************************************************/
/*名称: Ivoid Init_fm1702(uchar mode)
/*功能: 该函数实现对FM1702初始化操作 */
/*输入: mode:工作模式, 0:TYPEA模式 */
/* 1:TYPEB模式 */
/* 2:上海模式 */
/*输出: N/A */
/****************************************************************/
void Init_fm1702(uchar mode)
{
uint i;
MFRST = 1; //FM1715复位
for (i = 0; i < 0x3fff; i++)
{
_nop_();
}
MFRST = 0;
for (i = 0; i < 0x3fff; i++)
{
_nop_();
}
while(Command != 0) //等待Command = 0,FM1702复位成功
{
_nop_();
}
while(FM1702_Bus_Sel() == 0) //FM1702总线选择
{
_nop_();
}
//ClockQCControl =0x40;
//bitPhase =0xAD;
//Rxthreshold =0xFF;
//FIFOLevel =0x1A;
//IRQPinConfig =0x03;
/*
CWConductance =0x3F;
ModWidth =0x13;
RXControl1 =0x73;
DecoderControl =0x08;
bitPhase =0xAD;
Rxthreshold =0xFF;
Rxcontrol2 =0x41;
RxWait =0x06;
ChannelRedundancy =0x03;
CRCPresetLSB =0x63;
CRCPresetMSB =0x63;
FIFOLevel =0x08;
TimerClock =0x07;
TimerControl =0x06;
TimerReload =0x0A;
IRQPinConfig =0x02;
CryptoSelect =0x00;
//ClockQCControl =0x4F;
*/
//////////////////////////////
TimerClock =0x2B; //15us/per
TimerControl = 0x02; //发送结束开定时器接收开始关定时器
TimerReload = 0x42; //10ms定时
InterruptEn = 0x7f; //关所有中断
InterruptRq = 0x7f;
//MFOUTSelect =0x02; //* mf OUT 选择配置寄存器 */
//TxControl = 0x5b; //开启TX1 TX2
TxControl = 0x53; //开启TX1 TX2
//Rxcontrol2 =0x01;
Rxcontrol2 =0x03;
RxWait =0x06;
bitPhase =0xAD;
RXControl1 =0x73;
bufLed.reg =TxControl ;
if(mode ==TYPEA_MODE) //TYPE A mode
{
CryptoSelect = 0x00;
}
else if(mode == TYPEB_MODE) //TYPEB 模式
{
//CoderControl = 0x20;
//TypeBFraming = 0x05;
//DecoderControl = 0x19;
ChannelRedundancy = 0x24;
TxControl = 0x4b;
CWConductance = 0x3f;
ModConductance = 0xaf;
}
else if (mode == SHANGHAI_MODE) //上海模式
{
CryptoSelect = 0x01;
}
else ;
//Rxcontrol2=0x01;
}
/****************************************************************/
/*名称: Command_Send */
/*功能: 该函数实现向FM1702发送命令集的功能 */
/*输入: count, 待发送命令集的长度 */
/* buff, 指向待发送数据的指针 */
/* Comm_Set, 命令码 */
/*输出:
TRUE, 命令被正确执行 */
/* FALSE, 命令执行错误 */
/****************************************************************/
uchar Command_Send(uchar count,uchar idata *buff,uchar Comm_Set)
{
uint j;
uchar idata temp,temp1;
//InterruptEn = 0x7f;
//InterruptRq = 0x7f;
Command = 0x00;
Clear_FIFO();
Write_FIFO(count, buff);
Command = Comm_Set; //命令执行
ChannelRedundancy = 0x0f;
//for(j = 0; j<RF_TimeOut; j++) //检查命令执行否
for(j = 0; j<300; j++) //检查命令执行否
{
//temp = MFOUTSelect;
//temp = Command ;
temp = Command ;
temp1 = InterruptRq & 0x80;
if((temp == 0x00) || (temp1 == 0x80))
{
//if(bufTime.ledQF_Delay >=500)
//{
//bufTime.ledQF_Delay =0;
COLON =0;
//bufLed.reg = 0xFF;
//}
return TRUE;
}
}
return FALSE;
}
/*
***************************************************************/
/*名称: Read_E2 */
/*功能: 该函数实现从FM1702的EE中读出数据 */
/*输入:
lsb, EE地址(低字节) */
/* msb, EE地址(高字节) */
/* count, 待读出数据EE的字节个数 */
/* buff, 指向待读出数据的指针 */
/*输出:
TRUE, EE数据正确读出 */
/* FALSE, EE数据读出有误 */
/***************************************************************
*/
uchar Read_E2(uchar lsb,uchar msb,uchar count,uchar idata *buff)
{
uchar temp;
*buff=lsb;
*(buff+1)=msb;
*(buff+2)=count;
temp=Command_Send(3,buff,ReadE2);
Read_FIFO(buff);
if (temp==FALSE)
return(TRUE);
return(FALSE);
}
/*
***************************************************************/
/*名称: Write_E2 */
/*功能: 该函数实现向FM1715的EE中写入数据 */
/*输入:
lsb, EE地址(低字节) */
/* msb, EE地址(高字节) */
/* count, 待写入数据EE的字节个数 */
/* buff, 指向待写入数据的指针 */
/*输出:
TRUE, EE数据正确写入 */
/* FALSE, EE数据写入有误 */
/***************************************************************
*/
uchar Write_E2(uchar lsb,uchar msb,uchar count,uchar idata *buff)
{
uchar idata temp,i;
for(i = 0;i < count; i++)
{
*(buff + count - i + 2) = *(buff - i + count);
}
*buff = lsb;
*(buff + 1) = msb;
temp = Command_Send(count + 2, buff, WriteE2);
temp = SecondaryStatus;
temp = temp & 0x40;
if (temp == 0x40)
{
return TRUE;
}
return FALSE;
}
/****************************************************************/
/*名称: Clear_FIFO */
/*功能: 该函数实现清空FM1715中FIFO的数据 */
/*输入: N/A */
/*输出:
TRUE, FIFO被清空*/
/* FALSE, FIFO未被清空 */
/****************************************************************/
uchar Clear_FIFO(void)
{
uchar temp;
uint i;
temp =Control; //Clear FIFO
temp =(temp |0x01);
Control =temp;
//for(i=0;i<RF_TimeOut;i++) //检查FIFO是否为空
for(i=0;i<100;i++) //检查FIFO是否为空
{
temp =FIFOLength;
if(temp ==0)
{
return TRUE;
}
}
return FALSE;
}
/****************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -