⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rc500.c

📁 ARM7 SPI RC531驱动程序,数据手册
💻 C
📖 第 1 页 / 共 5 页
字号:
* 出口参数: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 + -