📄 fm1715.c
字号:
#else
for(i = 0; i < count; i++)
{
FIFOW(*(buff + i));
}
#endif
}
//第 29 页 共 52 页
//5.3.6 从FM1715 的FIFO 中读出x 字节数据
//****************************************************************
//*名称: Read_FIFO
//*功能: 该函数实现从FM1715 的FIFO 中读出x bytes 数据
//*输入: buff, 指向读出数据的指针
//*输出: N/A
//****************************************************************
uchar Read_FIFO(uchar idata *buff,uchar rlen)
{
uchar temp;
uchar i;
temp = FIFO_LengthR;
if (temp)
{
if (temp >= rlen)//24) //temp=255 时,会进入死循环
{ //因此增加FIFO_Length 越限判断
temp =rlen;// 24; //yanshouli,2003-12-2
}
for(i = 0;i < temp; i++)
{
*(buff + i) = FIFOR;
// buff[i] =FIFOR;
}
}
return temp;
}
/*
//重新初始化FM1702的内部寄存器值
uchar MfInOutSlaveConfig(void)
{
uchar temp;
uchar idata MSndBuffer[34];
CRCPresetLSBW(0x63);
CWConductanceW(0x3f);
ChannelRedundancyW(0x03);
MSndBuffer[0] = 0x10; // addr low byte
MSndBuffer[1] = 0x00; // addr high byte
MSndBuffer[2] = 0x00; // Page
MSndBuffer[3] = 0x58; // RegTxControl modsource 11,InvTx2,Tx2RFEn,TX1RFEn
MSndBuffer[4] = 0x3F; // RegCwConductance
MSndBuffer[5] = 0x3F; // RFU13
MSndBuffer[6] = 0x19; // RFU14
MSndBuffer[7] = 0x13; // RegModWidth
MSndBuffer[8] = 0x00; // RFU16
MSndBuffer[9] = 0x00; // RFU17
MSndBuffer[10] = 0x00; // Page
MSndBuffer[11] = 0x73; // RegRxControl1
MSndBuffer[12] = 0x08; // RegDecoderControl
MSndBuffer[13] = 0xAD;//0x6c; // RegBitPhase
MSndBuffer[14] = 0xFF; // RegRxThreshold
MSndBuffer[15] = 0x00; // RFU1D
MSndBuffer[16] = 0X41;//0x00; // RegRxControl2
MSndBuffer[17] = 0x00; // RegClockQControl
MSndBuffer[18] = 0x00; // Page
MSndBuffer[19] = 0x06; // RegRxWait
MSndBuffer[20] = 0x03; // RegChannelRedundancy
MSndBuffer[21] = 0x63; // RegCRCPresetLSB
MSndBuffer[22] = 0x63; // RegCRCPresetMSB
MSndBuffer[23] = 0x00; // RFU25
MSndBuffer[24] = 0x00;//0x04; // RegMfOutSelect enable mfout = manchester HT
MSndBuffer[25] = 0x00; // RFU27
// PAGE 5 FIFO, Timer and IRQ-Pin Configuration
MSndBuffer[26] = 0x00; // Page
MSndBuffer[27] = 0x08; // RegFIFOLevel
MSndBuffer[28] = 0x07; // RegTimerClock
MSndBuffer[29] = 0x06; // RegTimerControl
MSndBuffer[30] = 0x0A; // RegTimerReload
MSndBuffer[31] = 0x02; // RegIRqPinConfig
MSndBuffer[32] = 0x00; // RFU
MSndBuffer[33] = 0x00; // RFU
temp = Command_Send(34, MSndBuffer, WriteE2);
if (temp == TRUE)//FALSE) LJL 050415
{
return FM1715_OK;
}
else
{
return FM1715_Err;
}
}
*/
//第 30 页 共 52 页
//5.4 FM1715 卡片操作基本函数
//5.4.1 HALT
//****************************************************************
//*名称: MIF_Halt
//*功能: 该函数实现暂停MIFARE 卡
//*输入: N/A
//*输出: FM1715_OK: 应答正确
//* FM1715_PARITYERR: 奇偶校验错
//* FM1715_CRCERR: CRC 校验错
//* FM1715_NOTAGERR: 无卡
//****************************************************************
uchar MIF_Halt(void)
{
uchar temp;
uchar idata buffer[2];
CRCPresetLSBW(0x63);
CWConductanceW(0x3f);
ChannelRedundancyW(0x03);
*buffer = RF_CMD_HALT;
*(buffer + 1) = 0x00;
temp = Command_Send(2, buffer, Transceive);
if (temp == TRUE)//FALSE) LJL 050415
{
return FM1715_OK;
}
else
{
return FM1715_Err;
/*
temp = ErrorFlagR;
if ((temp & 0x02)==0x02)
{
return(FM1715_PARITYERR);
}
if ((temp & 0x04)==0x04)
{
return(FM1715_FRAMINGERR);
}
return(FM1715_NOTAGERR);
*/
}
}
//5.4.3 REQUEST
//****************************************************************
//*名称: Request
//*功能: 该函数实现对放入FM1715 操作范围之内的卡片的Request 操作
//*输入: mode: ALL(监测所以FM1715 操作范围之内的卡片)
//* STD(监测在FM1715 操作范围之内处于HALT 状态的卡片)
//*输出: FM1715_NOTAGERR: 无卡
//* FM1715_OK: 应答正确
//* FM1715_REQERR: 应答错误
//****************************************************************
uchar Request(uchar mode)
{
uchar temp;
uchar idata buffer[2];
// TxControl = 0x58;
// delay(1); //??????????? 1000
// TxControl = 0x5b;
CRCPresetLSBW(0x63);
CWConductanceW(0x3f);
buffer[0] = mode; //Request 模式选择
Bit_FrameW(0x07); //发送7bit
ChannelRedundancyW(0x03); //关闭CRC
TxControlW(0x5b);
ControlW(0x01); //屏蔽CRYPTO1 位
temp = Command_Send(1, buffer, Transceive);
if(temp == FALSE)
{
return FM1715_NOTAGERR;
}
if(Read_FIFO(buffer,2)>0) //从FIFO 中读取应答信息
{
// tagtype[0] = buffer[0];
// tagtype[1] = buffer[1];
return FM1715_OK;
}
else
return FM1715_Err;
}
//注temp1 = 03 ; 上海标准TOKEN卡
//temp1 = 04 ; MIFARE标准8K
//temp1 = 05 ; MIFARE标准TOKEN卡
//temp1 = 53 ; 上海标准8K卡
//此返回值为目前市场使用的各类卡片的返回结果将来可能有更多的返回类别
//第 33 页 共 52 页
//5.4.4 ANTICOLLISION
//****************************************************************
//*名称: AntiColl
//*功能: 该函数实现对放入FM1715 操作范围之内的卡片的防冲突检测
//*输入: N/A
//*输出: FM1715_NOTAGERR: 无卡
//* FM1715_BYTECOUNTERR: 接收字节错误
//* FM1715_SERNRERR: 卡片序列号应答错误
//* FM1715_OK: 卡片应答正确
//****************************************************************
uchar AntiColl(uchar *CardID)
{
uchar temp;
uchar i;
// uchar row,col;
// uchar pre_row;
uchar idata buffer[5];
// row = 0;
// col = 0;
// pre_row = 0;
CRCPresetLSBW(0x63);
CWConductanceW(0x3f);
ModConductanceW(0x3f);
buffer[0] = RF_CMD_ANTICOL;
buffer[1] = 0x20;
ChannelRedundancyW(0x03); //关闭CRC,打开奇偶校验
temp=Command_Send(2, buffer, Transceive);
while(1)
{
if(temp==FALSE)
{
return(FM1715_NOTAGERR);
}
temp = ErrorFlagR;
if((temp & 0x02)==0x02)
return(FM1715_PARITYERR);
if((temp & 0x04)==0x04)
return(FM1715_FRAMINGERR);
// temp = ErrorFlagR&0x01; //判断接収数据是否出错
if((temp & 0x01) == 0x00) //判断接収数据是否出错
{
if(Read_FIFO(buffer,5)>0)
{
temp = Check_UID(buffer); //校验收到的UID
if(temp == FALSE)
{
return(FM1715_SERNRERR);
}
for(i = 0; i < 4; i++)
{
CardID[i] = buffer[i];
}
return(FM1715_OK);
}
else
return FM1715_BYTECOUNTERR;
}
else
return FM1715_ANTICOLLERR;
/*
else
{
temp = CollPosR; //读取冲突检测寄存器
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);
}
*/
}
}
//****************************************************************
//*名称: GetCardID
//*功能: 该函数实现获取Mifare卡的IC号
//*输入: Mode: 寻卡模式RF_CMD_REQUEST_STD、RF_CMD_REQUEST_ALL
//*
//*输出: 操作状态码
//* 读出数据存于buffer 中
//****************************************************************
uchar GetCardID(uchar Mode,uchar *CardID)
{
uchar temp;
uchar ret_code=0;
delay_1ms(50); //为了降低功耗,在这里延时50毫秒再读卡,降低读卡频率
TxControlW(0x5B); //启动射频发射端口
temp=ControlR;
ControlW(temp&0xDF);//使读卡芯片退出待机状态
MIF_Halt(); //Halt
temp = Request(Mode);//RF_CMD_REQUEST_STD); //Request
if(temp != FM1715_OK)
{
ret_code=FM1715_REQERR;
}
else
{
temp = AntiColl(CardID); //AntiCol
if(temp != FM1715_OK)
ret_code=FM1715_ANTICOLLERR;
}
temp=ControlR;
ControlW(temp|0x20);//使读卡芯片处于待机状态
TxControlW(0x58); //关闭射频发射端口
return ret_code;
}
/*
//第 35 页 共 52 页
//5.4.5 SELECT
//****************************************************************
//*名称: Select_Card
//*功能: 该函数实现对放入FM1715 操作范围之内的某张卡片进行选择
//*输入: N/A
//*输出: FM1715_NOTAGERR: 无卡
//* FM1715_PARITYERR: 奇偶校验错
//* FM1715_CRCERR: CRC 校验错
//* FM1715_BYTECOUNTERR: 接收字节错误
//* FM1715_OK: 应答正确
//* FM1715_SELERR: 选卡出错
//****************************************************************
uchar Select_Card(void)
{
uchar temp,i;
CRCPresetLSBW(0x63);
CWConductanceW(0x3f);
buffer[0] = RF_CMD_SELECT;
buffer[1] = 0x70;
for(i = 0; i < 5; i++)
{
buffer[i+2]=UID[i];
}
ChannelRedundancyW(0x0f); //开启CRC,奇偶校验校验
temp=Command_Send(7,buffer,Transceive);
if(temp==FALSE)
{
return(FM1715_NOTAGERR);
}
else
{
temp=ErrorFlagR;
if ((temp & 0x02)==0x02)
return(FM1715_PARITYERR);
if((temp & 0x04)==0x04)
return(FM1715_FRAMINGERR);
if ((temp & 0x08)==0x08)
return(FM1715_CRCERR);
temp=FIFO_LengthR;
if (temp!=1)
return(FM1715_BYTECOUNTERR);
Read_FIFO(buffer); //从FIFO 中读取应答信息
temp = buffer[0];
// if ((temp==0x08) || (temp==0x88) || (temp==0x53)) //判断应答信号是否正确
if (temp!=0) //判断应答信号是否正确 //?????????
return(FM1715_OK);
else
return(FM1715_SELERR);
}
}
//第 36 页 共 52 页
//5.4.2 LOADKEY
//****************************************************************
//*名称: Load_keyE2
//*功能: 该函数实现把E2中密码存入FM1715的keybuffer中
//*输入: Secnr: EE起始地址
//*输出: True: 密钥装载成功
//* False: 密钥装载失败
//* 本程序是用E2P密码认证时使用的,是通过把FM1715的E2PROM里保存的密码发送到认证缓冲区进行卡密码认证
//****************************************************************
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 = ErrorFlagR & 0x40;
if (temp == 0x40)
{
return FALSE;
}
return TRUE;
}
//第 31 页 共 52 页
//5.4.2 LOADKEY
//****************************************************************
//*名称: Load_key_CPY
//*功能: 该函数实现把MCU单元中的密码存入FM1715 的keybuffer 中
//*输入: keybuffer: 密钥存放缓冲区
//*输出: True: 密钥装载成功
//* False: 密钥装载失败
//* 本程序是直接密码认证时使用的,是直接把MCU里保存的密码发送给FM1715的密码认证缓冲区进行卡密码认证
//****************************************************************
uchar Load_key_CPY(void)
{
uchar temp,i;
uchar ln = 0;
uchar hn = 0;
for(i = 0; i < 6; i++) //密码转换成RC531 密码格式?
{
ln =keybuffer[i] & 0x0f; //低4 位
hn = keybuffer[i] >> 4; //高4 位
buffer[i * 2 + 1] = (~ln << 4) | ln;
buffer[i * 2] = (~hn << 4) | hn;
}
temp = Command_Send(12, buffer, LoadKey);
temp = ErrorFlagR & 0x40;
if (temp == 0x40)
{
return FALSE;
}
return TRUE;
}
//第 32 页 共 52 页
//5.4.6 AUTHENTICATION
//****************************************************************
//*名称: Authentication
//*功能: 该函数实现密码认证的过程
//*输入: UID: 卡片序列号地址
//* SecNR: 扇区号
//* Mode: 认证模式 =0表示用密码A认证,=1表示用密码B认证
//*输出: FM1715_NOTAGERR: 无卡
//* FM1715_PARITYERR: 奇偶校验错
//* FM1715_CRCERR: CRC 校验错
//* FM1715_OK: 应答正确
//* FM1715_AUTHERR: 权威认证有错
//****************************************************************
uchar Authentication(uchar idata *UID,uchar SecNR,uchar mode)
{
uchar idata i;
uchar idata temp,temp1;
CRCPresetLSBW(0x63);
CWConductanceW(0x3f);
ModConductanceW(0x3f);
temp1 = ControlR;
temp1 = temp1 & 0xf7;
ControlW(temp1);
if (mode == 1) //AUTHENT1
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];
}
ChannelRedundancyW(0x0f); //开启CRC,奇偶校验校验
temp = Command_Send(6, buffer, Authent1);
if (temp == FALSE)
{
return FM1715_NOTAGERR;
}
temp = ErrorFlagR;
if ((temp & 0x02) == 0x02)
return FM1715_PARITYERR;
if((temp & 0x04) == 0x04)
return FM1715_FRAMINGERR;
if ((temp & 0x08) == 0x08)
return FM1715_CRCERR;
temp = Command_Send(0, buffer, Authent2); //AUTHENT2
if(temp == FALSE)
{
return FM1715_NOTAGERR;
//第 37 页 共 52 页
}
temp = ErrorFlagR;
if ((temp & 0x02) == 0x02)
return FM1715_PARITYERR;
if((temp & 0x04) == 0x04)
return FM1715_FRAMINGERR;
if ((temp & 0x08) == 0x08)
return FM1715_CRCERR;
temp1 = ControlR;
temp1 = temp1 & 0x08; //Crypto1on=1,验证通过
if (temp1 == 0x08)
{
return FM1715_OK;
}
return FM1715_AUTHERR;
}
//第 38 页 共 52 页
//5.4.7 READ
//****************************************************************
//*名称: MIF_Read
//*功能: 该函数实现读MIFARE 卡块的数值
//*输入: buff: 缓冲区首地址
//* Block_Adr: 块地址
//*输出: FM1715_NOTAGERR: 无卡
//* FM1715_PARITYERR: 奇偶校验错
//* FM1715_CRCERR: CRC 校验错
//* FM1715_BYTECOUNTERR: 接收字节错误
//* FM1715_OK: 应答正确
//****************************************************************
uchar MIF_READ(uchar idata *buff,uchar Block_Adr)
{
uchar idata temp;
CRCPresetLSBW(0x63);
CWConductanceW(0x3f);
ModConductanceW(0x3f);
ChannelRedundancyW(0x0f);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -