📄 rc500.c
字号:
* 出口参数:0正常,其它错误码
****************************************************************************/
char M500PiccCascAnticoll (unsigned char bcnt,unsigned char *snr)
{
unsigned char status = MI_OK;
char snr_in[4];
char complete = 0;
char nbytes = 0;
char nbits = 0;
char i = 0;
char byteOffset = 0;
unsigned char dummyShift1;
unsigned char dummyShift2;
M500PcdSetTmo(106);
memcpy((void *)snr_in,(void *)snr,4);
WriteIO(RegDecoderControl,0x28); //0x1a 在一个位冲突之后的任何位都屏蔽为0
ClearBitMask(RegControl,0x08); //0x09 与卡的所有数据通信都被加密
complete = 0;
while ((!complete) && (status == MI_OK) )
{//1
ResetInfo(MInfo); //清0
WriteIO(RegChannelRedundancy,0x03); //0x22 选择RF 信道上数据完整性检测的类型和模式
// 单独产生或者出现奇数的奇偶校验
// 奇偶校验位在每个字节后插入发送数据流中并会出现在接收据流的每个字节后
nbits = bcnt % 8;
if(nbits)
{ //"<<" > "|"
WriteIO(RegBitFraming,nbits << 4 | nbits); //0x0f 位方式帧的调节
nbytes = bcnt / 8 + 1;
if (nbits == 7)
{
MInfo.cmd = PICC_ANTICOLL1; //0x93
WriteIO(RegBitFraming,nbits);
}
}
else
{
nbytes = bcnt / 8;
}
SerBuffer[0] = 0x93;
SerBuffer[1] = 0x20 + ((bcnt/8) << 4) + nbits;
for (i = 0; i < nbytes; i++)
{
SerBuffer[i + 2] = snr_in[i];
}
MInfo.nBytesToSend = 2 + nbytes;
status = M500PcdCmd(PCD_TRANSCEIVE,(unsigned char *)SerBuffer,(MfCmdInfo *)&MInfo);
if (nbits == 7)
{
dummyShift1 = 0x00; ///////////////////////
for (i = 0; i < MInfo.nBytesReceived; i++)
{
dummyShift2 = SerBuffer[i];
SerBuffer[i] = (dummyShift1 >> (i+1)) | (SerBuffer[i] << (7-i));
dummyShift1 = dummyShift2;
}
MInfo.nBitsReceived -= MInfo.nBytesReceived;
if ( MInfo.collPos ) MInfo.collPos += 7 - (MInfo.collPos + 6) / 9;
}
if ( status == MI_OK || status == MI_COLLERR)
{//2
if ( MInfo.nBitsReceived != (40 - bcnt) )
{
status = MI_BITCOUNTERR;
}
else
{//3
byteOffset = 0;
if( nbits != 0 )
{
snr_in[nbytes - 1] = snr_in[nbytes - 1] | SerBuffer[0];
byteOffset = 1;
}
for ( i = 0 ; i < (4 - nbytes) ; i++)
{
snr_in[nbytes + i] = SerBuffer[i + byteOffset];
}
if (status != MI_COLLERR )
{
dummyShift2 = snr_in[0] ^ snr_in[1] ^ snr_in[2] ^ snr_in[3];
dummyShift1 = SerBuffer[MInfo.nBytesReceived - 1];
if (dummyShift2 != dummyShift1)
{
status = MI_SERNRERR;
}
else
{
complete = 1;
}
}
else
{
bcnt = bcnt + MInfo.collPos - nbits;
status = MI_OK;
}
}//3
}//2
}//1
if (status == MI_OK)
{
memcpy(snr,snr_in,4);
}
else
{
memcpy(snr,"0123",4);
}
ClearBitMask(RegDecoderControl,0x20);
return status;
}
/****************************************************************************
* 名 称:M500PiccCascSelect
* 功 能:选技卡
* 入口参数:snr 卡序列号
sak 返回值 卡类型
* 出口参数:0正常,其它错误码
****************************************************************************/
char M500PiccCascSelect(unsigned char *snr,unsigned char *sak)
{
char status = MI_OK;
M500PcdSetTmo(106);
WriteIO(RegChannelRedundancy,0x0F); //接收帧的最后字节被解释为CRC 字节
//对发送数据进行CRC 计算并将CRC 字节加到数据流中
//单独产生或者出现奇数的奇偶校验
//奇偶校验位在每个字节后插入发送数据流中并会出现在接收数据流的每个字节后
ClearBitMask(RegControl,0x08); //与卡的所有数据通信都被加密
ResetInfo(MInfo); //清0
SerBuffer[0] = 0x93;
SerBuffer[1] = 0x70;
memcpy((char *)SerBuffer + 2,(char *)snr,4);
SerBuffer[6] = SerBuffer[2] ^ SerBuffer[3] ^ SerBuffer[4] ^ SerBuffer[5];
MInfo.nBytesToSend = 7;
status = M500PcdCmd(PCD_TRANSCEIVE,(unsigned char *)SerBuffer,(MfCmdInfo *)&MInfo);
*sak = 0;
if (status == MI_OK)
{
if (MInfo.nBitsReceived != 8)
{
status = MI_BITCOUNTERR;
}
else
{
//SerBuffer[0]=SerBuffer[1]=SerBuffer[2]=6;
*sak = SerBuffer[0];
}
}
return status;
}
/****************************************************************************
* 名 称:M500PiccAuthE2
* 功 能:校验卡密码(E2)
* 入口参数:auth_mode 密码类型
snr 卡序列号
block 块号
* 出口参数:0正常,其它错误码
****************************************************************************/
char M500PiccAuthState( unsigned char auth_mode,unsigned char *snr,unsigned char block)
{
char status = MI_OK;
status = ReadIO(RegErrorFlag);
if (status != MI_OK)
{
if (status & 0x40)
{
status = MI_KEYERR;
}
else
{
status = MI_AUTHERR;
}
}
else
{
SerBuffer[0] = auth_mode;
SerBuffer[1] = block;
memcpy((char *)SerBuffer + 2,snr,4);
ResetInfo(MInfo);
MInfo.nBytesToSend = 6;
if ((status = M500PcdCmd(PCD_AUTHENT1,(unsigned char *)SerBuffer,(MfCmdInfo *)&MInfo)) == MI_OK)
{
if (ReadIO(RegSecondaryStatus) & 0x07) //不完全接收
{
status = MI_BITCOUNTERR;
}
else //完全接收
{
ResetInfo(MInfo);
MInfo.nBytesToSend = 0;
delay_1ms(1);
if ((status = M500PcdCmd(PCD_AUTHENT2,
(unsigned char *)SerBuffer,
(MfCmdInfo *)&MInfo)) == MI_OK)
{
if ( ReadIO(RegControl) & 0x08 ) //通信是否加密成功
{
status = MI_OK;
}
else
{
status = MI_AUTHERR;
}
}
}
}
}
return status;
}
/****************************************************************************
* 名 称:M500PiccAuthE2
* 功 能:校验卡密码(E2)
* 入口参数:auth_mode 密码类型
snr 卡序列号
keynr 扇区号
block 块号
* 出口参数:0正常,其它错误码
****************************************************************************/
char M500PiccAuthE2( unsigned char auth_mode,unsigned char *snr,
unsigned char keynr,unsigned char block)
{
char status = MI_OK;
unsigned short e2addr = (unsigned short)0x80 + keynr * 0x18;
unsigned char *e2addrbuf;
if (auth_mode == PICC_AUTHENT1B) //b密码
{
e2addr += 12;
}
e2addrbuf = (unsigned char *)&e2addr;
FlushFIFO(); //清FIFO
ResetInfo(MInfo); //清0
memcpy((void *)SerBuffer,(void *)e2addrbuf,2);
MInfo.nBytesToSend = 2;
if ((status=M500PcdCmd(PCD_LOADKEYE2,(unsigned char *)SerBuffer,(MfCmdInfo *)&MInfo)) == MI_OK)
{
status = M500PiccAuthState(auth_mode,snr,block);
}
return status;
}
/****************************************************************************
* 名 称:M500HostCodeKey
* 功 能:密码转换
* 入口参数:uncoded 原始密码
coded 标准密码
* 出口参数:0正常,其它错误码
****************************************************************************/
char M500HostCodeKey(unsigned char *uncoded, unsigned char *coded)
{
char status = MI_OK;
unsigned char cnt = 0;
unsigned char ln = 0;
unsigned char hn = 0;
for (cnt = 0; cnt < 6; cnt++)
{
ln = uncoded[cnt] & 0x0F;
hn = uncoded[cnt] >> 4;
coded[cnt * 2 + 1] = (~ln << 4) | ln;
coded[cnt * 2 ] = (~hn << 4) | hn;
}
return status;
}
/****************************************************************************
* 名 称:M500PiccAuthKey
* 功 能:直接校验密码
* 入口参数:auth_mode 密码类型
snr 卡序列号
keynr 扇区号
block 块号
* 出口参数:0正常,其它错误码
****************************************************************************/
char M500PiccAuthKey( unsigned char auth_mode,
unsigned char *snr,
unsigned char *keys,
unsigned char block)
{
char status = MI_OK;
// unsigned char i;
// M500PcdSetTmo(106);
FlushFIFO();
ResetInfo(MInfo);
memcpy((void *)SerBuffer,(void *)keys,12);
MInfo.nBytesToSend = 12;
if ((status=M500PcdCmd(PCD_LOADKEY,(unsigned char *)SerBuffer,(MfCmdInfo *)&MInfo)) == MI_OK)
{
status = M500PiccAuthState(auth_mode,snr,block);
}
else
{
//Uart1_SendByte(0x55);
}
return status;
}
/****************************************************************************
* 名 称:DownloadPassWord2
* 功 能:直接校验密码
* 入口参数:bank 所使用的块号
* 出口参数:0正常,其它错误码
****************************************************************************/
unsigned char DownloadPassWord2(unsigned char *password ,unsigned char bank)
{
unsigned char _data[12];
char status = MI_OK;
M500HostCodeKey(password,_data);
status = M500PiccAuthKey(0x60,(unsigned char *)MLastSelectedSnr,_data,bank);
return status;
}
/****************************************************************************
* 名 称:DownloadPassWord
* 功 能:内部效验密码
* 入口参数:bank 所使用的块号
* 出口参数:0正常,其它错误码
****************************************************************************/
unsigned char DownloadPassWord(unsigned char bank)
{
unsigned char fan;
fan=bank/4;
// A密码效验 卡序列号 区号 块号
return M500PiccAuthE2(0x60,(unsigned char *)MLastSelectedSnr,fan,bank);
}
/****************************************************************************
* 名 称:PcdWriteE2
* 功 能:保存内部密码
* 入口参数:startaddr 密码起始地址
length 密码长度
_data 密码
* 出口参数:0正常,其它错误码
****************************************************************************/
char PcdWriteE2(unsigned short startaddr,
unsigned char length,
unsigned char* _data)
{
char status = MI_OK;
ResetInfo(MInfo);
SerBuffer[0] = startaddr & 0xFF;
SerBuffer[1] = (startaddr >> 8) & 0xFF;
memcpy((char *)SerBuffer + 2,_data,length);
MInfo.nBytesToSend = length + 2;
status = M500PcdCmd(PCD_WRITEE2,
(unsigned char *)SerBuffer,
(MfCmdInfo *)&MInfo);
return status;
}
/****************************************************************************
* 名 称:M500PcdLoadKeyE2
* 功 能:修改内部密码
* 入口参数:key_type 密码类型
sector 扇区号
uncoded_keys 密码
* 出口参数:0正常,其它错误码
****************************************************************************/
char M500PcdLoadKeyE2(unsigned char key_type,
unsigned char sector,
unsigned char *uncoded_keys)
{
signed char status = MI_OK;
unsigned short e2addr = (unsigned short)0x80 + sector * 0x18;
unsigned char coded_keys[12];
if (key_type == PICC_AUTHENT1B)
{
e2addr += 12; // key B offset
}
if ((status = M500HostCodeKey(uncoded_keys,coded_keys)) == MI_OK)
{
status = PcdWriteE2(e2addr,12,coded_keys);
}
return status;
}
/****************************************************************************
* 名 称:ChangePassWord
* 功 能:修改内部密码
* 入口参数:password 密码
bank 所使用的块号
* 出口参数:0正常,其它错误码
****************************************************************************/
unsigned char ChangePassWord(unsigned char *password,unsigned char bank)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -