📄 fm1702.c
字号:
/*输入: 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;
SPIWrite(CRCPresetLSB,0x63);
SPIWrite(CWConductance,0x3f);
SPIWrite(ModConductance,0x3f);
SPIWrite(ChannelRedundancy,0x0f);
buff[0] = RF_CMD_READ;
buff[1] = Block_Adr;
temp = Command_Send(2, buff, Transceive);
if(temp == 0)
{
return FM1702_NOTAGERR;
}
temp = SPIRead(ErrorFlag);
if((temp & 0x02) == 0x02) return FM1702_PARITYERR;
if((temp & 0x04) == 0x04) return FM1702_FRAMINGERR;
if((temp & 0x08) == 0x08) return FM1702_CRCERR;
temp = SPIRead(FIFO_Length);
if(temp == 0x10)
{
Read_FIFO(buff);
return FM1702_OK;
}
else if(temp == 0x04)
{
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: 写卡块数据出错*/
/* FM1702_OK: 应答正确*/
/****************************************************************/
uchar MIF_Write(uchar idata *buff, uchar Block_Adr)
{
uchar idata temp;
uchar idata *F_buff;
SPIWrite(CRCPresetLSB,0x63);
SPIWrite(CWConductance,0x3f);
F_buff = buff + 0x10;
SPIWrite(ChannelRedundancy,0x07); /* Note: this line is for 1702, different from RC500*/
*F_buff = RF_CMD_WRITE;
*(F_buff + 1) = Block_Adr;
temp = Command_Send(2, F_buff, Transceive);
if(temp == FALSE)
{
return(FM1702_NOTAGERR);
}
temp = SPIRead(FIFO_Length);
if(temp == 0)
{
return(FM1702_BYTECOUNTERR);
}
Read_FIFO(F_buff);
temp = *F_buff;
switch(temp)
{
case 0x00: return(FM1702_NOTAUTHERR);
case 0x04: return(FM1702_EMPTY);
case 0x0a: break;
case 0x01: return(FM1702_CRCERR);
case 0x05: return(FM1702_PARITYERR);
default: return(FM1702_WRITEERR);
}
temp = Command_Send(16, buff, Transceive);
if(temp == TRUE)
{
return(FM1702_OK);
}
else
{
temp = SPIRead(ErrorFlag);
if((temp & 0x02) == 0x02)
return(FM1702_PARITYERR);
else if((temp & 0x04) == 0x04)
return(FM1702_FRAMINGERR);
else if((temp & 0x08) == 0x08)
return(FM1702_CRCERR);
else
return(FM1702_WRITEERR);
}
}
/****************************************************************/
/*名称: MIF_Increment */
/*功能: 该函数实现MIFARE卡自动增值操作*/
/*输入: buff: 四个字节数值起始地址*/
/* Block_Adr: 块地址*/
/*输出: FM1702_NOTAGERR: 无卡*/
/* FM1702_BYTECOUNTERR: 接收字节错误*/
/* FM1702_NOTAUTHERR: 未经权威认证*/
/* FM1702_EMPTY: 数据溢出错误*/
/* FM1702_CRCERR: CRC校验错*/
/* FM1702_PARITYERR: 奇偶校验错*/
/* FM1702_INCRERR: 卡片增款操作失败*/
/* FM1702_OK: 应答正确*/
/****************************************************************/
uchar MIF_Increment(uchar idata *buff, uchar Block_Adr)
{
uchar temp;
uchar idata *F_buff;
SPIWrite(CRCPresetLSB,0x63);
SPIWrite(CWConductance,0x3f);
F_buff = buff + 4;
*F_buff = RF_CMD_INC;
*(F_buff + 1) = Block_Adr;
SPIWrite(ChannelRedundancy,0x07);
temp = Command_Send(2, F_buff, Transceive);
if(temp == FALSE)
{
return FM1702_NOTAGERR;
}
temp = SPIRead(FIFO_Length);
if(temp == 0)
{
return FM1702_BYTECOUNTERR;
}
Read_FIFO(F_buff);
temp = *F_buff;
switch(temp)
{
case 0x00: /* break; */return(FM1702_NOTAUTHERR);
case 0x04: return(FM1702_EMPTY);
case 0x0a: break;
case 0x01: return(FM1702_CRCERR);
case 0x05: return(FM1702_PARITYERR);
default: return(FM1702_INCRERR);
}
temp = Command_Send(4, buff, Transmit);
if(temp == FALSE)
{
return FM1702_INCRERR;
}
return FM1702_OK;
}
/****************************************************************/
/*名称: MIF_Decrement */
/*功能: 该函数实现MIFARE卡自动减值操作*/
/*输入: buff: 四个字节数值起始地址*/
/* Block_Adr: 块地址*/
/*输出: FM1702_NOTAGERR: 无卡*/
/* FM1702_BYTECOUNTERR: 接收字节错误*/
/* FM1702_NOTAUTHERR: 未经权威认证*/
/* FM1702_EMPTY: 数据溢出错误*/
/* FM1702_CRCERR: CRC校验错*/
/* FM1702_PARITYERR: 奇偶校验错*/
/* FM1702_DECRERR: 卡片扣款操作失败*/
/* FM1702_OK: 应答正确*/
/****************************************************************/
uchar MIF_Decrement(uchar idata *buff, uchar Block_Adr)
{
uchar temp;
uchar idata *F_buff;
SPIWrite(CRCPresetLSB,0x63);
SPIWrite(CWConductance,0x3f);
F_buff = buff + 4;
*F_buff = RF_CMD_DEC;
*(F_buff + 1) = Block_Adr;
SPIWrite(ChannelRedundancy,0x07);
temp = Command_Send(2, F_buff, Transceive);
if(temp == FALSE)
{
return FM1702_NOTAGERR;
}
temp = SPIRead(FIFO_Length);
if(temp == 0)
{
return FM1702_BYTECOUNTERR;
}
Read_FIFO(F_buff);
temp = *F_buff;
switch(temp)
{
case 0x00: /* break; */return(FM1702_NOTAUTHERR);
case 0x04: return(FM1702_EMPTY);
case 0x0a: break;
case 0x01: return(FM1702_CRCERR);
case 0x05: return(FM1702_PARITYERR);
default: return(FM1702_DECRERR);
}
temp = Command_Send(4, buff, Transmit);
if(temp == FALSE)
{
return(FM1702_DECRERR);
}
return FM1702_OK;
}
/****************************************************************/
/*名称: MIF_Restore */
/*功能: 该函数实现MIFARE卡自动恢复,备份操作*/
/*输入: Block_Adr: 块地址*/
/*输出: FM1702_NOTAGERR: 无卡*/
/* FM1702_BYTECOUNTERR: 接收字节错误*/
/* FM1702_NOTAUTHERR: 未经权威认证*/
/* FM1702_EMPTY: 数据溢出错误*/
/* FM1702_CRCERR: CRC校验错*/
/* FM1702_PARITYERR: 奇偶校验错*/
/* FM1702_RESTERR: 卡片恢复,备份操作失败*/
/* FM1702_OK: 应答正确*/
/****************************************************************/
uchar MIF_Restore(uchar Block_Adr)
{
uchar temp, i;
SPIWrite(CRCPresetLSB,0x63);
SPIWrite(CWConductance,0x3f);
SPIWrite(ChannelRedundancy,0x07);
*RevBuffer = RF_CMD_RESTORE;
*(RevBuffer + 1) = Block_Adr;
temp = Command_Send(2, RevBuffer, Transceive);
if(temp == FALSE)
{
return FM1702_NOTAGERR;
}
temp = SPIRead(FIFO_Length);
if(temp == 0)
{
return FM1702_BYTECOUNTERR;
}
Read_FIFO(RevBuffer);
temp = *RevBuffer;
switch(temp)
{
case 0x00: /* break; */return(FM1702_NOTAUTHERR);
case 0x04: return(FM1702_EMPTY);
case 0x0a: break;
case 0x01: return(FM1702_CRCERR);
case 0x05: return(FM1702_PARITYERR);
default: return(FM1702_RESTERR);
}
for(i = 0; i < 4; i++) RevBuffer[i] = 0x00;
temp = Command_Send(4, RevBuffer, Transmit);
if(temp == FALSE)
{
return FM1702_RESTERR;
}
return FM1702_OK;
}
/****************************************************************/
/*名称: MIF_Transfer */
/*功能: 该函数实现MIFARE卡电子钱包保存操作*/
/*输入: Block_Adr: 块地址*/
/*输出: FM1702_NOTAGERR: 无卡*/
/* FM1702_BYTECOUNTERR: 接收字节错误*/
/* FM1702_NOTAUTHERR: 未经权威认证*/
/* FM1702_EMPTY: 数据溢出错误*/
/* FM1702_CRCERR: CRC校验错*/
/* FM1702_PARITYERR: 奇偶校验错*/
/* FM1702_TRANSERR: 卡片恢复,备份操作失败*/
/* FM1702_OK: 应答正确*/
/****************************************************************/
uchar MIF_Transfer(uchar Block_Adr)
{
uchar temp;
SPIWrite(CRCPresetLSB,0x63);
SPIWrite(CWConductance,0x3f);
SPIWrite(ChannelRedundancy,0x07);
RevBuffer[0] = RF_CMD_TRANSFER;
RevBuffer[1] = Block_Adr;
temp = Command_Send(2, RevBuffer, Transceive);
if(temp == FALSE)
{
return FM1702_NOTAGERR;
}
temp = SPIRead(FIFO_Length);
if(temp == 0)
{
return FM1702_BYTECOUNTERR;
}
Read_FIFO(RevBuffer);
temp = *RevBuffer;
switch(temp)
{
case 0x00: /* break; */return(FM1702_NOTAUTHERR);
case 0x04: return(FM1702_EMPTY);
case 0x0a: return(FM1702_OK);
case 0x01: return(FM1702_CRCERR);
case 0x05: return(FM1702_PARITYERR);
default: return(FM1702_TRANSERR);
}
}
#if 0
/****************************************************************/
/*名称: HL_Active */
/*功能: 该函数实现高级MIFARE卡激活命令*/
/*输入: Secnr: 扇区号*/
/* Block_Adr: 块地址*/
/*输出: 操作状态码*/
/* 读出数据存于RevBuffer中*/
/****************************************************************/
uchar HL_Active(uchar Block_Adr, uchar Mode)
{
uchar temp;
Secnr = Block_Adr / 4;
MIF_Halt(); /* Halt */
temp = Request(RF_CMD_REQUEST_STD);
if(temp != FM1702_OK)
{
return(FM1702_REQERR);
}
temp = AntiColl();
if(temp != FM1702_OK)
{
return(FM1702_ANTICOLLERR);
}
temp = Select_Card();
if(temp != FM1702_OK)
{
return(FM1702_SELERR);
}
Load_keyE2_CPY(Secnr, Mode); //%40
temp = Authentication(UID, Secnr, Mode);
if(temp != FM1702_OK)
{
return(FM1702_AUTHERR);
}
return FM1702_OK;
}
/****************************************************************/
/*名称: MIF_Initival */
/*功能: 该函数实现MIFARE卡初始化值操作*/
/*输入: buff: 四个字节初始化数值起始地址*/
/* Block_Adr: 块地址*/
/*输出: FM1702_NOTAGERR: 无卡*/
/* FM1702_BYTECOUNTERR: 接收字节错误*/
/* FM1702_NOTAUTHERR: 未经权威认证*/
/* FM1702_EMPTY: 数据溢出错误*/
/* FM1702_CRCERR: CRC校验错*/
/* FM1702_PARITYERR: 奇偶校验错*/
/* FM1702_WRITEERR: 写卡块数据出错*/
/* FM1702_OK: 应答正确*/
/****************************************************************/
uchar MIF_Initival(uchar idata *buff, uchar Block_Adr)
{
uchar idata temp;
uchar i;
for(i = 0; i < 4; i++)
{
*(buff + 4 + i) = ~(*(buff + i));
}
for(i = 0; i < 4; i++)
{
*(buff + 8 + i) = *(buff + i);
}
*(buff + 12) = Block_Adr;
*(buff + 13) = ~Block_Adr;
*(buff + 14) = Block_Adr;
*(buff + 15) = ~Block_Adr;
temp = MIF_Write(buff, Block_Adr);
return temp;
}
#endif
#if 0
/****************************************************************/
/*名称: HL_Read */
/*功能: 该函数实现高级读命令*/
/*输入: Secnr: 扇区号*/
/* Block_Adr: 块地址*/
/*输出: 操作状态码*/
/* 读出数据存于RevBuffer中*/
/****************************************************************/
uchar HL_Read(uchar idata *buff, uchar Block_Adr, uchar Mode)
{
uchar temp;
temp = HL_Active(Block_Adr, Mode);
if(temp != FM1702_OK)
{
return temp;
}
temp = MIF_READ(buff, Block_Adr);
if(temp != FM1702_OK)
{
return temp;
}
return FM1702_OK;
}
/****************************************************************/
/*名称: HL_Write */
/*功能: 该函数实现高级写命令*/
/*输入: buff: 待写入数据的首地址*/
/* Secnr: 扇区号*/
/* Block_Adr: 块地址*/
/*输出:操作状态码*/
/****************************************************************/
uchar HL_Write(uchar idata *buff, uchar Block_Adr, uchar Mode)
{
uchar temp;
temp = HL_Active(Block_Adr, Mode);
if(temp != FM1702_OK)
{
return temp;
}
temp = MIF_Write(buff, Block_Adr);
if(temp != FM1702_OK)
{
return FM1702_WRITEERR;
}
return FM1702_OK;
}
#endif
///////////////////////////////////////////////////////////////////////
// Delay 50us
///////////////////////////////////////////////////////////////////////
void delay_50us(uchar _50us)
{
while(_50us--)
{
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
/////////////////////////////////////////////////////////////////////////////////
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
}
}
///////////////////////////////////////////////////////////////////////
// Delay 10ms
///////////////////////////////////////////////////////////////////////
void delay_10ms(unsigned int _10ms)
{
#ifndef NO_TIMER2
RCAP2LH = RCAP2_10ms;
T2LH = RCAP2_10ms;
TR2 = TRUE;
while (_10ms--)
{
while (!TF2);
TF2 = FALSE;
}
TR2 = FALSE;
#else
while (_10ms--)
{
delay_50us(19);
if (CmdValid)
return;
delay_50us(20);
if (CmdValid)
return;
delay_50us(20);
if (CmdValid)
return;
delay_50us(20);
if (CmdValid)
return;
delay_50us(20);
if (CmdValid )
return;
delay_50us(20);
if (CmdValid)
return;
delay_50us(20);
if (CmdValid)
return;
delay_50us(20);
if (CmdValid)
return;
delay_50us(20);
if (CmdValid)
return;
delay_50us(19);
if (CmdValid)
return;
}
#endif
}
//////////////////////////////////////////////////////////////////////////////
// End of File
//////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -