📄 rc531.c
字号:
#include <absacc.h>
#include <intrins.h>
#include "main.h"
#include "globe.h"
#include "rc531.h"
//***********************************************************************//
// Copyright (c) 2003,上海复旦微电子股份有限公司应用系统部 //
// //
//* 文件标识:RC531.c //
//* 摘要:该文件提供了对RC531进行操作的底层驱动程序 //
//* 作者:梁磊 王文清 //
//* 完成日期: 2003年9月 //
//* 原作者:王文清 梁磊 //
//* 完成日期: 2003年9月 //
//***********************************************************************//
//API函数接口(注:用户在使用时,只需调用API函数,即可完成对RC531的操作)
//1.底层操作API命令集
//uchar Rc531_Bus_Sel(void) --> 实现对RC531的总线方式选择
//uchar Request(uchar mode) --> 实现对卡片的Request操作
//uchar Select_Card(void) --> 实现对卡片的选择操作
//uchar AntiColl(void) --> 实现对卡片的防冲突检测
//uchar Authentication(uchar idata *UID,uchar Block_Adr,uchar mode) --> 实现对卡片的认证操作
//uchar MIF_READ(uchar idata *buff,uchar Block_Adr) --> 实现对卡片扇区中数据的读出
//uchar MIF_Write(uchar idata *buff,uchar Block_Adr) --> 实现对卡片扇区中数据的写入
//uchar MIF_Initival(uchar idata *value,uchar Block_Adr) --> 实现对卡片中某扇区实现电子钱包应用进行初始化的操作
//uchar MIF_Increment(uchar idata *buff,uchar Block_Adr) --> 实现对卡片中电子钱包的增款操作
//uchar MIF_Decrement(uchar idata *buff,uchar Block_Adr) --> 实现对卡片中电子钱包的扣款操作
//uchar MIF_Transfer(uchar Block_Adr) --> 实现对卡片中电子钱包的备份操作
//uchar MIF_Restore(uchar Block_Adr) --> 实现对卡片中电子钱包的恢复,备份操作
//uchar MIF_Halt(void) --> 实现对操作卡片的挂起操作
//2.高级操作API命令集
//uchar HL_Initial(uchar idata *buff,uchar Block_Adr) --> 实现对卡片的高级初始化命令
//uchar HL_Read(uchar idata *buff,uchar Block_Adr) --> 实现对卡片的高级读命令
//uchar HL_Write(uchar idata *buff,uchar Block_Adr) --> 实现对卡片的高级写命令
//uchar HL_Increment(uchar idata *buff,uchar Block_Adr) --> 实现对卡片的高级增款命令
//uchar HL_Decrement(uchar idata *buff,uchar Block_Adr) --> 实现对卡片的高级扣款命令
//函数声明
void Save_UID(uchar row,uchar col,uchar length);
void Set_BitFraming(uchar row,uchar col);
void Write_FIFO(uchar count,uchar idata *buff);
void Read_FIFO(uchar idata *buff);
uchar MIF_READ(uchar idata *buff,uchar Block_Adr);
uchar MIF_Write(uchar idata *buff,uchar Block_Adr);
uchar MIF_Halt(void);
uchar MIF_Initival(uchar idata *value,uchar Block_Adr);
uchar MIF_Increment(uchar idata *buff,uchar Block_Adr);
uchar MIF_Decrement(uchar idata *buff,uchar Block_Adr);
uchar MIF_Restore(uchar Block_Adr);
uchar MIF_Transfer(uchar Block_Adr);
uchar Authentication(uchar idata *UID,uchar Block_Adr,uchar mode);
uchar Load_key_CPY(uchar idata *keybuff);
uchar Load_keyE2_CPY(uchar Secnr,uchar Mode);
uchar AntiColl(void);
uchar Select_Card(void);
uchar Read_E2(uchar lsb,uchar msb,uchar count,uchar idata *buff);
uchar Write_E2(uchar lsb,uchar msb,uchar count,uchar idata *buff);
uchar Request(uchar mode);
uchar Command_Send(uchar count,uchar idata * buff,uchar Comm_Set);
uchar Check_UID(void);
uchar Rc531_Bus_Sel(void);
uchar Judge_Req(uchar idata *buff);
uchar Clear_FIFO(void);
uchar HL_Initial(uchar idata *buff,uchar Block_Adr,uchar Mode);
uchar HL_Read(uchar idata *buff,uchar Block_Adr,uchar Mode);
uchar HL_Write(uchar idata *buff,uchar Block_Adr,uchar Mode);
uchar HL_Increment(uchar idata *buff,uchar Block_Adr,uchar Mode);
uchar HL_Decrement(uchar idata *buff,uchar Block_Adr,uchar Mode);
/*******************************************************************************************************/
/*名称: Rc531_Bus_Sel */
/*功能: 该函数实现对RC531操作的总线方式(并行总线,SPI)选择 */
/* */
/*输入: */
/* N/A */
/* */
/*输出: */
/* TRUE, 总线选择成功 */
/* FALSE, 总线选择失败 */
/*******************************************************************************************************/
uchar Rc531_Bus_Sel(void)
{
uchar i;
Page_Sel=0x80;
for(i=0;i<RF_TimeOut;i++)
{
if(Command==0x00)
{
Page_Sel=0x00;
return(TRUE);
}
}
return(FALSE);
}
/********************************************************************************************************/
/*名称: Request */
/*功能: 该函数实现对放入RC531操作范围之内的卡片的Request操作 */
/* */
/*输入: */
/* mode: ALL(监测所以RC531操作范围之内的卡片) */
/* STD(监测在RC531操作范围之内处于HALT状态的卡片) */
/* */
/*输出: */
/* FM222_NOTAGERR: 无卡 */
/* FM222_OK: 应答正确 */
/* FM222_REQERR: 应答错误 */
/********************************************************************************************************/
uchar Request(uchar mode)
{
uchar idata temp;
buffer[0]=mode; //Request模式选择
Bit_Frame=0x07; //发送7bit
ChannelRedundancy=0x00; //关闭CRC和奇偶校验
temp=Control;
temp=temp & (0xf7);
Control=temp; //屏蔽CRYPTO1位
temp=Command_Send(1,buffer,Transceive);
if(temp == FALSE)
{
return(FM222_NOTAGERR);
}
Read_FIFO(buffer); //从FIFO中读取应答信息
temp=Judge_Req(buffer); //判断应答信号是否正确
if (temp==TRUE)
{
tagtype[0]=buffer[0];
tagtype[1]=buffer[1];
return(FM222_OK);
}
else
return(FM222_REQERR);
}
/********************************************************************************************************/
/*名称: Select_Card */
/*功能: 该函数实现对放入RC531操作范围之内的某张卡片进行选择 */
/* */
/*输入: */
/* N/A */
/* */
/*输出: */
/* FM222_NOTAGERR: 无卡 */
/* FM222_PARITYERR: 奇偶校验错 */
/* FM222_CRCERR: CRC校验错 */
/* FM222_BYTECOUNTERR: 接收字节错误 */
/* FM222_OK: 应答正确 */
/* FM222_SELERR: 选卡出错 */
/********************************************************************************************************/
uchar Select_Card(void)
{
uchar temp,i;
buffer[0]=RF_CMD_SELECT;
buffer[1]=0x70;
for(i=0;i<5;i++)
buffer[i+2]=UID[i];
ChannelRedundancy=0x0f; //开启CRC,奇偶校验校验
temp=Command_Send(7,buffer,Transceive);
if(temp==FALSE)
return(FM222_NOTAGERR);
else
{
temp=ErrorFlag;
if ((temp & 0x02)==0x02)
return(FM222_PARITYERR);
if((temp & 0x04)==0x04)
return(FM222_FRAMINGERR);
if ((temp & 0x08)==0x08)
return(FM222_CRCERR);
temp=FIFO_Length;
if (temp!=1)
return(FM222_BYTECOUNTERR);
Read_FIFO(buffer); //从FIFO中读取应答信息
if (*buffer==0x08 || *buffer==0x88) //判断应答信号是否正确
return(FM222_OK);
else
return(FM222_SELERR);
}
}
/********************************************************************************************************/
/*名称: AntiColl */
/*功能: 该函数实现对放入RC531操作范围之内的卡片的防冲突检测 */
/* */
/*输入: */
/* N/A */
/* */
/*输出: */
/* FM222_NOTAGERR: 无卡 */
/* FM222_BYTECOUNTERR: 接收字节错误 */
/* FM222_SERNRERR: 卡片序列号应答错误 */
/* FM222_OK: 卡片应答正确 */
/********************************************************************************************************/
uchar AntiColl(void)
{
uchar temp;
uchar i;
uchar row,col;
uchar pre_row;
row=0;
col=0;
pre_row=0;
buffer[0]=RF_CMD_ANTICOL;
buffer[1]=0x20;
ChannelRedundancy=0x03; //关闭CRC,打开奇偶校验
temp=Command_Send(2,buffer,Transceive);
while(1)
{
if(temp==FALSE)
return(FM222_NOTAGERR);
temp=ErrorFlag;
// if((temp & 0x02)==0x02)
// return(FM222_PARITYERR);
// if((temp & 0x04)==0x04)
// return(FM222_FRAMINGERR);
temp=FIFO_Length;
if (temp==0)
return(FM222_BYTECOUNTERR);
Read_FIFO(buffer);
Save_UID(row,col,temp); //将收到的UID放入UID数组中
temp=ErrorFlag; //判断接収数据是否出错
temp=temp & 0x01;
if(temp==0x00)
{
temp=Check_UID(); //校验收到的UID
if(temp==FALSE)
return(FM222_SERNRERR);
return(FM222_OK);
}
else
{
temp=CollPos; //读取冲突检测寄存器
row=temp/8;
col=temp%8;
buffer[0]=RF_CMD_ANTICOL;
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);
}
}
}
/********************************************************************************************************/
/*名称: Command_Send */
/*功能: 该函数实现向RC531发送命令集的功能 */
/* */
/*输入: */
/* count, 待发送命令集的长度 */
/* buff, 指向待发送数据的指针 */
/* Comm_Set, 命令码 */
/* */
/*输出: */
/* TRUE, 命令被正确执行 */
/* FALSE, 命令执行错误 */
/********************************************************************************************************/
uchar Command_Send(uchar count,uchar idata * buff,uchar Comm_Set)
{
uint j;
uchar idata temp;
Command=0x00;
Clear_FIFO();
Write_FIFO(count,buff);
Command=Comm_Set; //命令执行
for(j=0;j<RF_TimeOut;j++) //检查命令执行否
{
temp=Command;
if(temp==0x00)
return(TRUE);
}
return(FALSE);
}
/*******************************************************************************************************/
/*名称: Clear_FIFO */
/*功能: 该函数实现清空RC531中FIFO的数据 */
/* */
/*输入: */
/* N/A */
/* */
/*输出: */
/* TRUE, FIFO被清空 */
/* FALSE, FIFO未被清空 */
/*******************************************************************************************************/
uchar Clear_FIFO(void)
{
uchar temp;
uint i;
temp=Control; //清空FIFO
temp=(temp | 0x01);
Control=temp;
for(i=0;i<RF_TimeOut;i++) //检查FIFO是否被清空
{
temp=FIFO_Length;
if(temp==0)
return(TRUE);
}
return(FALSE);
}
/********************************************************************************************************/
/*名称: Write_FIFO */
/*功能: 该函数实现向RC531的FIFO中写入x bytes数据 */
/* */
/*输入: */
/* count, 待写入字节的长度 */
/* buff, 指向待写入数据的指针 */
/* */
/*输出: */
/* N/A */
/********************************************************************************************************/
void Write_FIFO(uchar count,uchar idata *buff)
{
uchar i;
for(i=0;i<count;i++)
FIFO=*(buff+i);
}
/********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -