📄 mfrc522.c
字号:
** 返 回 值: 执行结果
** 描 述:
****************************************************************************************/
char PiccRead(unsigned char addr, unsigned char idata *_data)
{
char status = STATUS_SUCCESS;
char tmp = 0;
unsigned char idata SerBuffer[16];
ResetInfo();
SerBuffer[0] = MIFARE_READ;
SerBuffer[1] = addr;
MInfo.nBytesToSend = 2;
SetTimeOut(100);
status = M522PcdCmd(JCMD_TRANSCEIVE,
SerBuffer);
if (status != STATUS_SUCCESS)
{
if (status != STATUS_IO_TIMEOUT ) // no timeout occured
{
if (MInfo.nBitsReceived == 4)
{
SerBuffer[0] &= 0x0f;
if ((SerBuffer[0] & 0x0a) == 0)
{
status = STATUS_AUTHENT_ERROR;
}
else
{
status = STATUS_INVALID_FORMAT;
}
}
}
}
else // Response Processing
{
if (MInfo.nBytesReceived != 16)
{
status = STATUS_ACCESS_DENIED;
}
else
{
memcopy(_data,SerBuffer,16);
}
}
return status;
}
char MFCheckAck(char Status, unsigned char Rsponse)
{
if(Status == STATUS_ACK_SUPPOSED)
{
if (MInfo.nBitsReceived != 4)
{
Status = STATUS_BITCOUNT_ERROR;
}
else
{
Rsponse &= 0x0f;
switch(Rsponse)
{
case 0x00:
Status = STATUS_AUTHENT_ERROR;
break;
case 0x0a:
Status = STATUS_SUCCESS;
break;
case 0x01:
Status = STATUS_INVALID_FORMAT;
break;
default:
Status = STATUS_OTHER_ERROR;
break;
}
}
}
return Status;
}
/****************************************************************************************
** 函数原型: char PiccWrite(unsigned char addr, unsigned char idata *_data)
** 函数功能: 向指定的扇区写入16字节数据
** 入口参数: unsigned char addr ; 块号
** unsigned char idata *_data ; 写入的数据(16字节)
** 出口参数:
** 返 回 值: 执行结果
** 描 述:
****************************************************************************************/
char PiccWrite( unsigned char addr, unsigned char idata *_data)
{
char status = STATUS_SUCCESS;
unsigned char idata SerBuffer[16];
ResetInfo();
SerBuffer[0] = MIFARE_WRITE;
SerBuffer[1] = addr;
MInfo.nBytesToSend = 2;
SetTimeOut(200);
status = M522PcdCmd(JCMD_TRANSCEIVE,
SerBuffer);
status = MFCheckAck(status, SerBuffer[0]);
if ( status == STATUS_SUCCESS)
{
SetTimeOut(50);
ResetInfo();
memcopy(SerBuffer,_data,16);
MInfo.nBytesToSend = 16;
status = M522PcdCmd(JCMD_TRANSCEIVE,
SerBuffer);
status = MFCheckAck(status, SerBuffer[0]);
}
return status;
}
/****************************************************************************************
** 函数原型: char PiccULWrite( unsigned char addr,unsigned char idata *_data)
** 函数功能: 向指定的块写入4字节数据(MF IC U1)
** 入口参数: unsigned char addr ; 块号
** unsigned char idata *_data ; 写入的数据(4字节)
** 出口参数:
** 返 回 值: 执行结果
** 描 述:
****************************************************************************************/
char PiccULWrite( unsigned char addr,unsigned char idata *_data)
{
char status = STATUS_SUCCESS;
unsigned char idata SerBuffer[6];
ResetInfo();
SerBuffer[0] = PICC_ULWRITE;
SerBuffer[1] = addr;
memcopy(&SerBuffer[2],_data,4);
MInfo.nBytesToSend = 6;
SetTimeOut(200);
status = M522PcdCmd(JCMD_TRANSCEIVE,SerBuffer);
status = MFCheckAck(status, SerBuffer[0]);
return status;
}
/****************************************************************************************
** 函数原型: char PiccValue(unsigned char OperMode,unsigned char addr,
** unsigned char idata *value,unsigned char trans_addr)
** 函数功能: 值块操作函数(增、减或者传输)
** 入口参数: unsigned char OperMode ; 操作模式(增、减)
** unsigned char addr ; 块号
** unsigned char idata *value ; 操作值块的值
** unsigned char trans_addr ; 保存操作结果的块号
** 出口参数: -
** 返 回 值: 执行结果
** 描 述:
****************************************************************************************/
char PiccValue( unsigned char OperMode,unsigned char addr,
unsigned char idata *value,unsigned char trans_addr)
{
char status = STATUS_SUCCESS;
unsigned char idata SerBuffer[4];
ResetInfo();
SerBuffer[0] = OperMode;
SerBuffer[1] = addr;
MInfo.nBytesToSend = 2;
SetTimeOut(200);
status = M522PcdCmd(JCMD_TRANSCEIVE,
SerBuffer);
status = MFCheckAck(status, SerBuffer[0]);
if ( status == STATUS_SUCCESS)
{
SetTimeOut(100);
ResetInfo();
memcopy(SerBuffer,value,4);
MInfo.nBytesToSend = 4;
status = M522PcdCmd(JCMD_TRANSCEIVE,
SerBuffer);
if (status == STATUS_IO_TIMEOUT)
{
status = STATUS_SUCCESS;
}
else
{
status = STATUS_OTHER_ERROR;
}
}
if ( status == STATUS_SUCCESS)
{
ResetInfo();
SerBuffer[0] = MIFARE_TRANSFER;
SerBuffer[1] = trans_addr;
MInfo.nBytesToSend = 2;
status = M522PcdCmd(JCMD_TRANSCEIVE,
SerBuffer);
status = MFCheckAck(status, SerBuffer[0]);
}
return status;
}
/****************************************************************************************
** 函数原型: char PiccActivate(unsigned char br,unsigned char req_code,
** unsigned char idata *atq, unsigned char idata *sak,
** unsigned char idata *uid, unsigned char idata *uid_len)
** 函数功能: 卡片激活
** 入口参数: unsigned char req_code ; 请求模式
** 出口参数: unsigned char idata *atq ; ATQ 2字节
unsigned char idata *sak ; SAK
unsigned char idata *uid ; UID
unsigned char idata *uid_len ; UID_Len
** 返 回 值: 执行结果
** 描 述: 组合函数
****************************************************************************************/
#if PICC_ACTIVATE_EN
char PiccActivate(unsigned char br,unsigned char req_code,
unsigned char idata *atq,
unsigned char idata *sak,
unsigned char idata *uid,
unsigned char idata *uid_len)
{
// unsigned char cascade_level;
unsigned char sel_code;
unsigned char uid_index;
char status;
// unsigned char cmdASEL;
bit SecReqFlag = FALSE; //第二次请求标志
*uid_len = 0;
br = br;
while(1)
{
if ((status=PiccRequest(req_code,atq))==STATUS_SUCCESS)
{
if((atq[0] & 0x1F) == 0x00) // check lower 5 bits, for tag-type
// all tags within this 5 bits have to
// provide a bitwise anticollision
{
status = STATUS_NOBITWISEANTICOLL;
}
break;
}
else
{
if(SecReqFlag)
break;
else
{
SecReqFlag = TRUE;
continue;
}
}
}
//Get UID in 1 - 3 levels (standard, [double], [triple] )
//-------
// if(!br)
// {
// sel_code = PICC_ANTICOLL1;
// }
// else
// {
// status = MI_BAUDRATE_NOT_SUPPORTED;
// }
if (status == STATUS_SUCCESS)
{
// cascade_level = 0;
uid_index = 0;
sel_code = SELECT_CASCADE_LEVEL_1;
do
{
//Select code depends on cascade level
// sel_code = cmdASEL + (cascade_level << 1);
// cmdASEL = PICC_ANTICOLL1; // reset anticollistion level for calculation
//ANTICOLLISION
status = PiccCascAnticoll( sel_code, 0, &uid[uid_index]);
//SELECT
if (status == STATUS_SUCCESS)
{
status = PiccCascSelect(sel_code, &uid[uid_index], sak);
if (status == STATUS_SUCCESS)
{
// cascade_level++;
sel_code += 2;
//we differ cascaded and uncascaded UIDs
if (*sak & 0x04) // if cascaded, bit 2 is set in answer to select
{
//this UID is cascaded, remove the cascaded tag that is
//0x88 as first of the 4 byte received
//memmove(&uid[uid_index], &uid[uid_index + 1], 3);
uid[uid_index] = uid[uid_index + 1];
uid[uid_index + 1] = uid[uid_index + 2];
uid[uid_index + 2] = uid[uid_index + 3];
uid_index += 3;
*uid_len += 3;
}
else
{
//this UID is not cascaded -> the length is 4 bytes
// uid_index += 4;
*uid_len += 4;
}
}
}
}
while((status == STATUS_SUCCESS) // error status
&& (*sak & 0x04) // no further cascade level
&& (sel_code < 0x99)); // highest cascade level is reached
}
if (status == STATUS_SUCCESS)
{
//Exit function, if cascade level is triple and sak indicates another
//cascase level.
if ((sel_code == 0x99) && (*sak & 0x04))
{
*uid_len = 0;
status = STATUS_SERNR_ERROR;
}
}
return (status);
}
#endif
//=======================================================================================
// 其他实用的操作函数
//=======================================================================================
/****************************************************************************************
** 函数原型: char PcdRfReset(unsigned char ms)
** 函数功能: RF场复位
** 入口参数: unsigned char ms ; RF场关闭的时间
** 出口参数: -
** 返 回 值: 执行结果
** 描 述:
****************************************************************************************/
#if PCD_RFRESET_EN
char PcdRfReset(unsigned char ms)
{
// Tx2RF-En, Tx1RF-En disablen
RcModifyReg(JREG_TXCONTROL,0,TxConMask);
if(ms)
{
while(ms--)
{
// delay_50us(20);
}
// Tx2RF-En, Tx1RF-En enable
RcModifyReg(JREG_TXCONTROL,1,TxConMask);
}
return MI_OK;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -