📄 fm1702.c
字号:
/*名称: Write_FIFO */
/*功能: 该函数实现向FM1715的FIFO中写入x bytes数据 */
/*输入:
count, 待写入字节的长度 */
/* buff, 指向待写入数据的指针 */
/*输出: N/A */
/****************************************************************/
void Write_FIFO(uchar count,uchar idata *buff)
{
uchar i;
for(i=0;i<count;i++)
{
FIFOData =*(buff+i);
}
}
/****************************************************************/
/*名称: Read_FIFO */
/*功能: 该函数实现从FM1715的FIFO中读出x bytes数据 */
/*输入: buff, 指向读出数据的指针 */
/*输出: N/A */
/****************************************************************/
uchar Read_FIFO(uchar idata *dBuf)
{
uchar temp;
uint i;
temp =FIFOLength;
if(temp ==0)
{
return 0;
}
if(temp >= 24) //temp=255,会进入死循环,因此增加FIFO_length越界判断
{
temp=24;
}
for(i=0;i<temp;i++)
{
*dBuf = FIFOData;
dBuf ++;
}
return temp;
}
//******************************************************
//******************************************************
/*
FM1702卡片操作基本函数
****************************************************************
名称: MIF_Halt
功能: 该函数实现暂停MIFARE卡
输入: N/A
输出:
FM1702_OK: 应答正确
FM1702_PARITYERR: 奇偶校验错
FM1702_CRCERR: CRC校验错
FM1702_NOTAGERR: 无卡
****************************************************************
*/
uchar MIF_Halt(void)
{
uchar temp;
CRCPresetLSB =0x63;
CWConductance =0x3F;
ChannelRedundancy =0x03;
*buffer=RF_CMD_HALT;
*(buffer+1)=0x00;
//temp=Command_Send(2,buffer,Transmit);
temp=Command_Send(2,buffer,Transceive);
if(temp ==TRUE )
//if(temp == FALSE)
{
return FM1702_OK;
}
else
{
temp = ErrorFlag;
if((temp&0x02)==0x02)
{
return(FM1702_PARITYERR);
}
if((temp&0x04)==0x04)
{
return(FM1702_FRAMINGERR);
}
return(FM1702_NOTAGERR);
}
}
/*
LOADKEY
***************************************************************
名称: Load_keyE2
功能: 该函数实现把E2中密码存入FM1715的keybuffer中
输入:
Secnr: EE起始地址
输出:
True: 密钥装载成功
False: 密钥装载失败
/***************************************************************
*/
uchar Load_keyE2_CPY(uchar Secnr,uchar Mode)
{
uchar temp;
uchar msb = 0;
uchar lsb = 0;
temp = Secnr * 12;
if (Mode == 0)
{
if(temp >=0x80) //计算密码存放地址
{
lsb=temp =0x80;
msb = 0x01;
}
else
{
msb =0x00;
lsb =temp + 0x80;
}
}
else
{
msb = 0x01;
lsb = temp + 0x40;
}
buffer[0] = lsb;
buffer[1] = msb;
temp = Command_Send(2, buffer, LoadKeyE2);
temp = ErrorFlag & 0x40;
if (temp == 0x40)
{
return FALSE;
}
return TRUE;
}
/*
***************************************************************/
/*名称: Request */
/*功能: 该函数实现对放入FM1715操作范围之内的卡
片的Request操作 */
/*输入:
mode:
ALL(监测所以FM1715操作范围之内的卡片) */
/* STD(监测在FM1715操作范围之内处于HALT状态的卡片) */
/*输出:
/*FM1715_NOTAGERR: 无卡 */
/* FM1715_OK: 应答正确 */
/* FM1715_REQERR: 应答错误 */
/***************************************************************
*/
uchar Request(uchar mode)
{
uchar temp;
CRCPresetLSB = 0x63;
CWConductance = 0x3f;
BitFraming = 0x07; //发送7bit
ChannelRedundancy = 0x07; //关闭接收电路CRC
buffer[0] =mode ; //Request模式选择
temp = Control;
temp = temp & (0xF7);
Control = temp; //屏蔽CRYPTO1位
//Control = 0X01; //屏蔽CRYPTO1位
temp = Command_Send(1, buffer, Transceive);
if(temp == FALSE)
{
return FM1702_NOTAGERR;
}
Read_FIFO(buffer); //从FIFO中读取应答信息
temp = Judge_Req(buffer); //判断应答信号是否正确
if (temp == TRUE)
{
tagtype[0] = buffer[0];
tagtype[1] = buffer[1];
return FM1702_OK;
}
return FM1702_REQERR;
}
/*
anticollision
**************************************************************
名称: AntiColl
功能: 该函数实现对放入FM1702操作范围之内的卡
片的防冲突检测
输入: N/A
输出:
FM1702_NOTAGERR: 无卡
FM1702_BYTECOUNTERR: 接收字节错误
FM1702_SERNRERR: 卡片序列号应答错误
FM1702_OK: 卡片应答正确
***************************************************************
*/
uchar AntiColl(void)
{
uchar temp;
uchar i;
uchar row,col;
uchar pre_row;
row=0;
col=0;
pre_row=0;
CRCPresetLSB =0x63;
CWConductance =0x3f;
//ModConductance =0x3f;
// ChannelRedundancy =0x03; //closed CRC,start parity
buffer[0] =RF_CMD_ANTICOL;
buffer[1] =0x20;
ChannelRedundancy=0x03; //closed CRC,start parity
temp=Command_Send(2,buffer,Transceive);
while(1)
{
if(temp==FALSE)
{
return(FM1702_NOTAGERR);
}
temp = ErrorFlag;
if((temp & 0x02)==0x02)
return(FM1702_PARITYERR);
if((temp & 0x04)==0x04)
return(FM1702_FRAMINGERR);
temp=FIFOLength;
if (temp==0)
{
return FM1702_BYTECOUNTERR;
}
Read_FIFO(buffer);
Save_UID(row, col, temp); //将收到的UID 放入UID 数组中
//Show_UID(); //显示UID
temp=ErrorFlag; //判断接收数据是否出错
temp=temp&0x01;
if(temp==0x00)
{
temp=Check_UID(); //校验收到的UID
if(temp==FALSE)
{
return(FM1702_SERNRERR);
}
return(FM1702_OK);
}
else
{
temp =CollPos; //读取冲突检测寄存器read collision register
row =temp/8;
col =temp%8;
buffer[0]=RF_CMD_ANTICOL; //set the count that the data to be sent
Set_BitFraming(row+pre_row,col); //设置待发送数据的字节数
pre_row=pre_row+row;
for(i=0;i<pre_row+1;i++)
{
buffer[i+2]=UID[i];
}
if(col!=0x00)
{
row=pre_row+1;
}
else
{
row=pre_row;
}
temp=Command_Send(row+2,buffer,Transceive);
}
}
}
/*
SELECT
***************************************************************
名称: Select_Card
功能: 该函数实现对放入FM1702操作范围之内的某张
卡片进行选择
输入: N/A
输出:
FM1702_NOTAGERR: 无卡
FM1702_PARITYERR: 奇偶校验错
FM1702_CRCERR: CRC校验错
FM1702_BYTECOUNTERR: 接收字节错误
FM1702_OK: 应答正确
FM1702_SELERR: 选卡出错
****************************************************************
*/
uchar Select_Card(void)
{
uchar temp,i;
CRCPresetLSB = 0x63;
CWConductance = 0x3F;
buffer[0] =RF_CMD_SELECT;
buffer[1] =0x70;
for(i=0;i<5;i++)
{
buffer[i+2]=UID[i];
}
ChannelRedundancy=0x0F;
temp=Command_Send(7, buffer, Transceive);
if(temp==FALSE)
{
return(FM1702_NOTAGERR);
}
else
{
temp=ErrorFlag;
if((temp&0x02)==0x02)
return(FM1702_PARITYERR);
if((temp&0x04)==0x04)
return(FM1702_FRAMINGERR);
if((temp&0x08)==0x08)
return(FM1702_CRCERR);
temp =FIFOLength;
if(temp !=1)
return(FM1702_BYTECOUNTERR);
Read_FIFO(buffer); //从FIFO中读取应答信息Read FIFO information
temp=*buffer;
if ((temp == 0x08) ||(temp==0x88) ||(temp ==0x53)) //判断应答信号是否正确//check ack signal
return(FM1702_OK);
else
return(FM1702_SELERR);
}
}
/*
AUTHENTICATION
**************************************************************
名称: Authentication
功能: 该函数实现密码认证的过程
输入: UID: 卡片序列号地址
SecNR: 扇区号
mode: 模式
输出:
FM1702_NOTAGERR: 无卡
FM1702_PARITYERR: 奇偶校验错
FM1702_CRCERR: CRC校验错
FM1702_OK: 应答正确
FM1702_AUTHERR: 权威认证有错
/***************************************************************
*/
uchar Authentication(uchar idata *UID,uchar SecNR, uchar mode)
{
uchar idata i;
uchar idata temp,temp1;
CRCPresetLSB=0x63;
CWConductance=0x3f;
//ModConductance=0x3f;
temp1=Control;
temp1=temp1&0xf7;
Control=temp1;
if(mode ==1) //AUTHENT1 authentication
buffer[0]=RF_CMD_AUTH_LB;
else
buffer[0]=RF_CMD_AUTH_LA;
buffer[1]=SecNR*4 +3;
for(i=0;i<4;i++)
{
buffer[2+i]=UID[i];
}
ChannelRedundancy=0x0f; //开启CRC,奇偶校验校验start crc,parity verify
temp =Command_Send(6,buffer,Authent1);
if(temp==FALSE)
{
return FM1702_NOTAGERR;
}
temp =ErrorFlag;
if((temp&0x02) ==0x02)
return FM1702_PARITYERR;
if((temp&0x04)==0x04)
return FM1702_FRAMINGERR;
if((temp&0x08)==0x08)
return FM1702_CRCERR;
temp=Command_Send(0,buffer,Authent2); //Authent2
if(temp==FALSE)
{
return FM1702_NOTAGERR;
}
temp=ErrorFlag;
if((temp&0x02)==0x02)
return FM1702_PARITYERR;
if((temp&0x04)==0x04)
return FM1702_FRAMINGERR;
if((temp&0x08)==0x08)
return FM1702_CRCERR;
temp1=Control;
temp1=temp1&0x08;
if(temp1==0x08)
{
return FM1702_OK;
}
return FM1702_AUTHERR;
}
/*
***************************************************************
名称: MIF_Read
功能: 该函数实现读MIFARE卡块的数值
输入: buff: 缓冲区首地址
Block_Adr: 块地址
输出:
FM1702_NOTAGERR: 无卡
FM1702_PARITYERR: 奇偶校验错
FM1702_CRCERR: CRC校验错
FM1702_BYTECOUNTERR: 接收字节错误
FM1702_OK: 应答正确
/***************************************************************
*/
uchar MIF_Read(uchar idata *buff,uchar Block_Adr)
{
uchar idata temp;
CRCPresetLSB=0x63;
CWConductance=0x3f;
//ModConductance=0x3f; //FM1702无此register
ChannelRedundancy=0x0f;
//InterruptRq=0x7f;
buff[0]=RF_CMD_READ;
buff[1]=Block_Adr;
temp=Command_Send(2,buff,Transceive);
if(temp==0)
{
return FM1702_NOTAGERR;
}
temp=ErrorFlag;
if((temp&0x02)==0x02)
return FM1702_PARITYERR;
if((temp&0x04)==0x04)
return FM1702_FRAMINGERR;
if((temp&0x08)==0x08)
return FM1702_CRCERR;
temp=FIFOLength;
if(temp==0x10) //8K卡读数据长度为16 ,8k card read data length is 16
{
Read_FIFO(buff);
return FM1702_OK;
}
else if(temp==0x04) //Token 卡读数据长度为16 。Token card read data length is 16
{
Read_FIFO(buff);
return FM1702_OK;
}
else
{
return FM1702_BYTECOUNTERR;
}
}
/*
**************************************************************
名称: MIF_Write
功能: 该函数实现写MIFARE卡块的数值
输入: buff: 缓冲区首地址
Block_Adr: 块地址
输出: FM1702_NOTAGERR: 无卡
FM1702_BYTECOUNTERR: 接收字节错误
FM1702_NOTAUTHERR: 未经权威认证
FM1702_EMPTY: 数据溢出错误
FM1702_CRCERR: CRC校验错
FM1702_PARITYERR: 奇偶校验错
FM1702_WRITEERR: 写卡块数据出错
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -