Beispiel #1
0
/////////////////////////////////////////////////////////////////////
//功    能:复位RC522
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdReset(void)
{
	//PORTD|=(1<<RC522RST);
	SET_RC522RST;
    delay_ns(10);
	//PORTD&=~(1<<RC522RST);
	CLR_RC522RST;
    delay_ns(10);
	//PORTD|=(1<<RC522RST);
	SET_RC522RST;
    delay_ns(10);
    WriteRawRC(CommandReg,PCD_RESETPHASE);
	WriteRawRC(CommandReg,PCD_RESETPHASE);
    delay_ns(10);
    
    WriteRawRC(ModeReg,0x3D);            //和Mifare卡通讯,CRC初始值0x6363
    WriteRawRC(TReloadRegL,30);           
    WriteRawRC(TReloadRegH,0);
    WriteRawRC(TModeReg,0x8D);
    WriteRawRC(TPrescalerReg,0x3E);
	
	WriteRawRC(TxAutoReg,0x40);//必须要
   
    return MI_OK;
}
Beispiel #2
0
///////////////////
///防冲撞寻卡号
///@param pSnr 返回的卡片序列号 4字节
///@retval 是否成功
///////////////////
bool MFRC522::PcdAntiColl(unsigned char *pSnr)
{
	bool status;
    unsigned char i,snr_check=0;
    unsigned int  unLen;
    unsigned char ucComMF522Buf[MFRC522_MaxReceiveLen]; 
    

    ClearBitMask(MFRC522_Status2Reg,0x08);
    WriteRawRC(MFRC522_BitFramingReg,0x00);
    ClearBitMask(MFRC522_CollReg,0x80);
    ucComMF522Buf[0] = MFRC522_PICC_ANTICOLL1;
    ucComMF522Buf[1] = 0x20;

    status = PcdComPicc(MFRC522_PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen);

    if (status)
    {
    	 for (i=0; i<4; i++)
         {   
             *(pSnr+i)  = ucComMF522Buf[i];
             snr_check ^= ucComMF522Buf[i];
         }
         if (snr_check != ucComMF522Buf[i])
         {   status = false;    }
    }
    SetBitMask(MFRC522_CollReg,0x80);
    return status;
}
Beispiel #3
0
void ClearBitMask(uint8_t   reg,uint8_t   mask)
{
	FUNCTION() ;
	char   tmp = 0x0;
	tmp = ReadRawRC(reg);
	WriteRawRC(reg, tmp & ~mask);  // clear bit mask
}
Beispiel #4
0
/////////////////////////////////////////////////////////////////////
//功    能:防冲撞
//参数说明: pSnr[OUT]:卡片序列号,4字节
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////  
char PcdAnticoll(unsigned char *pSnr)
{
    char status;
    unsigned char i,snr_check=0;
    unsigned int  unLen;
    unsigned char ucComMF522Buf[MAXRLEN]; 
    

    ClearBitMask(Status2Reg,0x08);
    WriteRawRC(BitFramingReg,0x00);
    ClearBitMask(CollReg,0x80);
 
    ucComMF522Buf[0] = PICC_ANTICOLL1;
    ucComMF522Buf[1] = 0x20;

    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen);

    if (status == MI_OK)
    {
    	 for (i=0; i<4; i++)
         {   
             *(pSnr+i)  = ucComMF522Buf[i];
             snr_check ^= ucComMF522Buf[i];
         }
         if (snr_check != ucComMF522Buf[i])
         {   status = MI_ERR;    }
    }
    
    SetBitMask(CollReg,0x80);
    return status;
}
Beispiel #5
0
/////////////////////////////////////////////////////////////////////
//功    能:寻卡
//参数说明: req_code[IN]:寻卡方式
//                0x52 = 寻感应区内所有符合14443A标准的卡
//                0x26 = 寻未进入休眠状态的卡
//          pTagType[OUT]:卡片类型代码
//                0x4400 = Mifare_UltraLight
//                0x0400 = Mifare_One(S50)
//                0x0200 = Mifare_One(S70)
//                0x0800 = Mifare_Pro(X)
//                0x4403 = Mifare_DESFire
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdRequest(unsigned char req_code,unsigned char *pTagType)
{
   char status;  
   unsigned int  unLen;
   unsigned char ucComMF522Buf[MAXRLEN]; 

   ClearBitMask(Status2Reg,0x08);
   WriteRawRC(BitFramingReg,0x07);
   SetBitMask(TxControlReg,0x03);
 
   ucComMF522Buf[0] = req_code;

   status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen);
   
   if ((status == MI_OK) && (unLen == 0x10))
   {    
       *pTagType     = ucComMF522Buf[0];
       *(pTagType+1) = ucComMF522Buf[1];
   }
   else
   {   status = MI_ERR;  
 


	}
   
   return status;
}
Beispiel #6
0
char PcdRequest(uint8_t req_code,uint8_t *pTagType)
{
	FUNCTION() ;
	char   status;
	uint8_t   unLen;
	uint8_t   ucComMF522Buf[MAXRLEN];

	WriteRawRC(BitFramingReg,0x07);
	ucComMF522Buf[0] = req_code;

	status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen);
	if ((status == TAG_OK) && (unLen == 0x10))
	{
		*pTagType     = ucComMF522Buf[0];
		*(pTagType+1) = ucComMF522Buf[1];
	}
	else if (status == TAG_COLLISION) {
//		printf("ATQA %02x%02x\n",ucComMF522Buf[0],ucComMF522Buf[1]);
	}
	else if (status!=TAG_NOTAG) {
		status = TAG_ERR;
	}

	return status;
}
Beispiel #7
0
void SetBitMask(uint8_t   reg,uint8_t   mask)
{
	FUNCTION() ;
	char   tmp = 0x0;
	tmp = ReadRawRC(reg);
//	printf("tmp --------------> by jaosn 0x%x\n",tmp);
	WriteRawRC(reg,tmp | mask);  // set bit mask
}
Beispiel #8
0
char PcdAnticoll(uint8_t cascade, uint8_t *pSnr)
{
	FUNCTION() ;
	char   status;
	uint8_t   i,snr_check=0;
	uint8_t   unLen;
	uint8_t   ucComMF522Buf[MAXRLEN];
	uint8_t   pass=32;
	uint8_t	  collbits=0;

	i=0;
	WriteRawRC(BitFramingReg,0x00);
	do {
		ucComMF522Buf[0] = cascade;
		ucComMF522Buf[1] = 0x20+collbits;
		//	WriteRawRC(0x0e,0);
		status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2+i,ucComMF522Buf,&unLen);
		if (status == TAG_COLLISION) {
			collbits=ReadRawRC(CollReg)&0x1f;
			if (collbits==0) collbits=32;
			i=(collbits-1)/8 +1;
//			printf ("--- %02x %02x %02x %02x %d\n",ucComMF522Buf[0],ucComMF522Buf[1],ucComMF522Buf[2],ucComMF522Buf[3],unLen);
			ucComMF522Buf[i-1]|=(1<<((collbits-1)%8));
			ucComMF522Buf[5]=ucComMF522Buf[3];
			ucComMF522Buf[4]=ucComMF522Buf[2];
			ucComMF522Buf[3]=ucComMF522Buf[1];
			ucComMF522Buf[2]=ucComMF522Buf[0];
			WriteRawRC(BitFramingReg,(collbits % 8));
//			printf (" %d %d %02x %d\n",collbits,i,ucComMF522Buf[i+1],collbits % 8);
		}
	} while (((--pass)>0)&&(status==TAG_COLLISION));

	if (status == TAG_OK)
	{
		for (i=0; i<4; i++)
		{
			*(pSnr+i)  = ucComMF522Buf[i];
			snr_check ^= ucComMF522Buf[i];
		}
		if (snr_check != ucComMF522Buf[i])
		{   status = TAG_ERR;    }
	}

	return status;
}
Beispiel #9
0
/////////////////////////////////////////////////////////////////////
//功    能:复位RC522
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdReset(void)
{
	//unsigned char i;
    MF522_RST_SET;

		Tos_TaskDelay(1);                 

    MF522_RST_CLR;

		Tos_TaskDelay(1);                   

    MF522_RST_SET;

		Tos_TaskDelay(1);                  
	
    WriteRawRC(CommandReg,PCD_RESETPHASE);

		Tos_TaskDelay(1);                   
	
    
    WriteRawRC(ModeReg,0x3D);            //和Mifare卡通讯,CRC初始值0x6363
    WriteRawRC(TReloadRegL,30);           
    WriteRawRC(TReloadRegH,0);
    WriteRawRC(TModeReg,0x8D);
    WriteRawRC(TPrescalerReg,0x3E);
   WriteRawRC(TxAutoReg,0x40);
    return MI_OK;
}
Beispiel #10
0
void CalulateCRC(uint8_t *pIn ,uint8_t   len,uint8_t *pOut )
{
	uint8_t   i,n;
	ClearBitMask(DivIrqReg,0x04);
	WriteRawRC(CommandReg,PCD_IDLE);
	SetBitMask(FIFOLevelReg,0x80);
	for (i=0; i<len; i++)
	{   WriteRawRC(FIFODataReg, *(pIn +i));   }
	WriteRawRC(CommandReg, PCD_CALCCRC);
	i = 0xFF;
	do
	{
		n = ReadRawRC(DivIrqReg);
		i--;
	}
	while ((i!=0) && !(n&0x04));
	pOut [0] = ReadRawRC(CRCResultRegL);
	pOut [1] = ReadRawRC(CRCResultRegM);
}
Beispiel #11
0
/**
  * @brief  寻卡
  * @param  
  *		@req_code[IN]:	寻卡方式 PICC_REQALL/PICC_REQIDL
  * 		0x52 = 寻感应区内所有符合14443A标准的卡
  *         0x26 = 寻未进入休眠状态的卡
  *		@pTagType[OUT]:	卡片类型代码
  *        	0x0002 = Mifare_One(S70)
  *       	0x0004 = Mifare_One(S50) 	白卡
  8       	0x0008 = Mifare_Pro			校园卡
  *      	0x0010 = Mifare_Light
  *      	0x0044 = Mifare_UltraLight
  *      	0x0304 = Mifare_ProX
  *        	0x0344 = Mifare_DesFire
  *		1. ATQA 的实际作用有两个,
  *			一个是告诉读写器自己是否遵循防冲突机制,
  *			其次,通过 ATQA 可以获知卡片的序列号(即UID)的长度
  *     2. 以 ATQA 判断卡片的类型是不准确的
  *		3. 有 ATQA 是 0044H 和 0344H,但不属于 Mifare UltraLight 和 Mifare Desfire。
  *		   而是一种新的7字节的Mifare S50卡。
  *	@ret 成功返回 MI_OK/ 错误代码 MI_BITCOUNTERR、MI_COLLERR
  * @global none
  * @attention: 
  *		调用 PcdCmdProcess()与卡通讯
  */
signed char PiccRequest(unsigned char req_code, unsigned char *pTagType)
{
	signed char status;
	struct TranSciveBuffer MfComData;
	struct TranSciveBuffer *pi;
	pi = &MfComData;

	//****************************** initialize ******************************
	WriteRawRC(RegChannelRedundancy,0x03);	// 奇校验(RxCRC and TxCRC disable, parity enable)
											// 在 ISO14443A 下进一步配置
	ClearBitMask(RegControl,0x08);			// 数据加密,disable Crypto-1 unit
	WriteRawRC(RegBitFraming,0x07);		    // 最后一个字节发送七位,0x52/0x26最高位均为0
	SetBitMask(RegTxControl,0x03);			// 管脚TX1/TX2上的输出信号将传递调制的13.56MHz能量载波
											// Tx2RF-En, Tx1RF-En enable

	PcdSetTmo(4);		                    // 寻卡超时阈值4.83ms,通过超时标志位判断是否超时
											// ISO14443A 场配置为 PcdSetTmo(1)

	MfComData.MfCommand = PCD_TRANSCEIVE;	// 发送并接受命令
	MfComData.MfLength  = 1;				// 发送数据长度1
	MfComData.MfData[0] = req_code;			// M1卡寻卡命令字 PICC_REQIDL或 PICC_REQALL

	status = PcdCmdProcess(pi);			// 发送并接收,与卡进行通讯
	
	#ifdef __MYDEBUG__
	USART_TransmitOne(0xdd);
	USART_TransmitOne(status&0xFF);
	USART_TransmitOne(MfComData.mfcurrent&0xFF);
	for(i=0; i<MfComData.mfcurrent; i++){
		USART_TransmitOne(MfComData.MfData[i]);
	}
	#endif

	if (MI_OK == status){    
		if (MfComData.MfLength != 0x10){   	// 卡片类型代码,16 bits
			return MI_BITCOUNTERR;   
		}
		*pTagType     = MfComData.MfData[0];
		*(pTagType+1) = MfComData.MfData[1];
	}
	 
	return status;
}
Beispiel #12
0
/////////////////////////////////////////////////////////////////////
//用MF522计算CRC16函数
/////////////////////////////////////////////////////////////////////
void CalulateCRC(unsigned char *pIndata,unsigned char len,unsigned char *pOutData)
{
    unsigned char i,n;
    ClearBitMask(DivIrqReg,0x04);
    WriteRawRC(CommandReg,PCD_IDLE);
    SetBitMask(FIFOLevelReg,0x80);
    for (i=0; i<len; i++)
    {   WriteRawRC(FIFODataReg, *(pIndata+i));   }
    WriteRawRC(CommandReg, PCD_CALCCRC);
    i = 0xFF;
    do 
    {
        n = ReadRawRC(DivIrqReg);
        i--;
    }
    while ((i!=0) && !(n&0x04));
    pOutData[0] = ReadRawRC(CRCResultRegL);
    pOutData[1] = ReadRawRC(CRCResultRegM);
}
Beispiel #13
0
void MFRC522::PCDInit()
{
	WriteRawRC(MFRC522_CommandReg,MFRC522_PCD_RESETPHASE); //想启动寄存器写入复位命令
	tskmgr.DelayMs(1);
	WriteRawRC(MFRC522_ModeReg,0x3D);   //定义发送和接收的模式,和Mifare卡通讯,CRC初始值0x6363
    WriteRawRC(MFRC522_TReloadRegL,30); //定时器重装值
    WriteRawRC(MFRC522_TReloadRegH,0);  //定时器重装值
    WriteRawRC(MFRC522_TModeReg,0x8D);  //定时器模式设置
    WriteRawRC(MFRC522_TPrescalerReg,0x3E);//预分频设置
    WriteRawRC(MFRC522_TxAskReg,0x40);     //传输调制设置:强制100%ASK调制独立的ModGsPReg的寄存器设置
	
	PcdAntennaOff();//关载波
	tskmgr.DelayMs(1);
	PcdAntennaOn();//开载波
	tskmgr.DelayMs(1);
}
/////////////////////////////////////////////////////////////////////
//功    能:复位RC522
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdReset(void)
{
    SET_RC522RST;
    Delay_NOP_us(1);
   CLR_RC522RST;
    Delay_NOP_us(1);
   SET_RC522RST;
     Delay_NOP_us(1);
    WriteRawRC(CommandReg,PCD_RESETPHASE);				 //启动卡操作
    Delay_NOP_us(1);
    
    WriteRawRC(ModeReg,0x3D);            //和Mifare卡通讯,CRC初始值0x6363
    WriteRawRC(TReloadRegL,30);           
    WriteRawRC(TReloadRegH,0);
    WriteRawRC(TModeReg,0x8D);			
    WriteRawRC(TPrescalerReg,0x3E);
    WriteRawRC(TxAutoReg,0x40);     
    return MI_OK;
}
Beispiel #15
0
bool MFRC522::FindCard(unsigned char whichTag,unsigned char *pTagType)
{
	bool status=false;unsigned int  unLen=0;      //存放接收到的数据的长度
	unsigned char ucComMF522Buf[MFRC522_MaxReceiveLen];  //存放接收到的数据,这里不直接使用pTagType是保险,防止用户传入长度太短的数组,导致数组越界程序崩溃

	ClearBitMask(MFRC522_Status2Reg,0x08);//清MIFAREe认证标志
	WriteRawRC(MFRC522_BitFramingReg,0x07);//面向位的帧调节,置位最后一个字节的位数,当此标志位0时,代表数据发送完毕
	SetBitMask(MFRC522_TxControlReg,0x03);//使能管脚TX1和TX2经载波后发送

	status = PcdComPicc(MFRC522_PCD_TRANSCEIVE,&whichTag,1,ucComMF522Buf,&unLen);

	if ((status == true) && (unLen == 0x10))
	{    
	   *pTagType     = ucComMF522Buf[0];
	   *(pTagType+1) = ucComMF522Buf[1];
	}
	else
	{   status = false;   }

	return status;
}
Beispiel #16
0
//////////////////////////////////////////////////////////////////////
//设置RC632的工作方式 
//////////////////////////////////////////////////////////////////////
char M500PcdConfigISOType(u8   type)
{
   if (type == 'A')                     //ISO14443_A
   { 
       ClearBitMask(Status2Reg,0x08);
       WriteRawRC(ModeReg,0x3D);//3F
       WriteRawRC(RxSelReg,0x86);//84
       WriteRawRC(RFCfgReg,0x7F);   //4F
   	   WriteRawRC(TReloadRegL,30);//tmoLength);// TReloadVal = 'h6a =tmoLength(dec) 
	   WriteRawRC(TReloadRegH,0);
       WriteRawRC(TModeReg,0x8D);
	   WriteRawRC(TPrescalerReg,0x3E);
	   delay_ns(1000);
       PcdAntennaOn();
   }
   else{ return 1; }
   
   return MI_OK;
}
Beispiel #17
0
/////////////////////////////////////////////////////////////////////
//功    能:复位RC522
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdReset()
{
    RST522_1;
    _NOP();
    RST522_0;
    _NOP();
    RST522_1;
    _NOP();
    WriteRawRC(CommandReg,PCD_RESETPHASE);
    _NOP();
  
    WriteRawRC(ModeReg,0x3D);
    WriteRawRC(TReloadRegL,30);
    WriteRawRC(TReloadRegH,0);
    WriteRawRC(TModeReg,0x8D);
    WriteRawRC(TPrescalerReg,0x3E);
   
    return MI_OK;
}
Beispiel #18
0
/**
  * @brief  14443A 防冲突循环 ANTICOLLISION 命令
  * @param  
  *		unsigned char *pSnr:	每个串联级别的 UID CLn
  *		unsigned char SelType:	ANTICOLLISION 命令的 SEL 部分,
  *								0x93 为级别一,0x95 为级别二,0x97 为级别三
  *	@ret 成功返回 MI_OK/ 错误代码 MI_BITCOUNTERR、MI_COLLERR
  * @global none
  * @attention: 
  *		调用 PcdCmdProcess()与卡通讯
  */
signed char PiccAnticollisionLoop(unsigned char *pSnr, unsigned char SelType)
{
    signed char status;
    unsigned char i;
    unsigned char ucBytes;							// number of bytes known
    unsigned char ucBits;							// remaining number of bits
    unsigned char snr_check = 0;					// snr_xor vs snr_check
    unsigned char ucCollPosition = 0;				// record CollPos
    unsigned char ucTemp;
    unsigned char ucSnr[5] = {0, 0, 0, 0 ,0};		// local snr and BCC
	
    unsigned char dummyShift1;      				// dummy byte for snr shifting
    unsigned char dummyShift2;      				// dummy byte for snr shifting
	
	/*
	 * struct TranSciveBuffer{
		unsigned char MfCommand;		// MFRC500命令字或 M1卡命令字
		unsigned int  MfLength;			// 发送数据长度(/byte)或接收数据长度(/bit)
		unsigned char MfData[128];		// 发送数据或接收数据临时缓冲区
		unsigned int mfcurrent;			// 接收字节数
	   };
	 */
    struct TranSciveBuffer MfComData;
    struct TranSciveBuffer *pi;
	memset(MfComData.MfData, 0, 128);	// initialize buffer to zeros.
    pi = &MfComData;
    
	
	// ****************************** Registers Initialisation ******************************
    WriteRawRC(RegDecoderControl, 0x28);			// 启用 ZeroAfterColl
													// 在一个位冲突之后的任何位都屏蔽为 0,
													// 由 ISO14443A 定义的防冲突机制进行处理
    ClearBitMask(RegControl,0x08);					// disable crypto 1 unit
    WriteRawRC(RegChannelRedundancy,0x03);			// RxCRC and TxCRC disable, parity enable
    PcdSetTmo(3);									// medium timeout (4.833 ms)


	// ****************************** Anticollision Loop ******************************
    do
    {
		// -------------------- 更新 ucBits、ucBytes,设置 RegBitFraming --------------------
        ucBits = (ucCollPosition) % 8;				// remaining number of bits
		// 不完整字节需额外处理
        if (ucBits != 0){
            ucBytes = ucCollPosition / 8 + 1;		// 不足一个字节也需要按一个字节计数
			
			// RxAlign[6:4] 用于位方式帧的接收,定义了接收的第一个位存储在 FIFO 的位置,
			// 		更多的位存储在后面的位位置。
			// TxLastBits[2:0] 用于位方式帧的发送,定义要发送的最后一个字节的位数目。
            WriteRawRC(RegBitFraming, (ucBits << 4) + ucBits);		// TxLastBits/RxAlign
			
			// in order to solve an inconsistancy in the anticollision sequence
			// (will be solved soon), the case of 7 bits has to be treated in a
			// separate way - 官方文档:强烈建议不要使用 RxAlign=7 以防止数据丢失!!			
            if (ucBits == 7){
                WriteRawRC(RegBitFraming, ucBits); 	// reset RxAlign to zero,TxLastBits=ucBits
            }
        }
        else{
             ucBytes = ucCollPosition / 8;			// 没有不足一个字节的情况
        }
	
		
		// -------------------------- 构建发送命令信息 --------------------------
        MfComData.MfCommand = PCD_TRANSCEIVE;
        MfComData.MfData[0] = SelType;				// PICC_ANTICOLL1
		/*
		 * NVB 初始值为 0x20,表示该命令只含有 2 个字节,即"0x93+0x20",不含 UID 数据,
		 * 		MIFARE 卡须返回全部 UID 字节作为响应。
		 * 若返回的 UID 数据有位冲突的情况发生,则根据冲突位置更新 NVB 值。
		 * 在搜索循环中,随着 UID 已知比特数的加入,NVB 不断增加,直到 0x70 为止。
		 *		它表示除了"0x93+0x70"两个命令字节外,还有 UID0~UID3 和 BCC 5个UID数据字节。
		 * 此时命令字节共有 7 个,防冲突命令转变为卡片选择命令。
		 * BCC 只有在 UID CLn 为 40bit 才有,是前面 5 个字节的异或!!!
		 */
        MfComData.MfData[1] = 0x20 + ((ucCollPosition / 8) << 4) + (ucBits & 0x0F);
        for (i=0; i<ucBytes; i++){					// 发送缓冲区描述
	        MfComData.MfData[i + 2] = ucSnr[i];
	    }
	    MfComData.MfLength = ucBytes + 2;			// 发送数据字节数
	
	    status = PcdCmdProcess(pi);
		
		#ifdef __MYDEBUG__
		USART_TransmitOne((unsigned char)0xcc);
		USART_TransmitOne(status);					// 此处应为 MI_OK/MI_COLLERR
		USART_TransmitOne(MfComData.MfLength);
		USART_TransmitOne(MfComData.mfcurrent);
		for(i=0; i<MfComData.mfcurrent; i++){
			USART_TransmitOne(MfComData.MfData[i]);
		}
		#endif
		
		
		// -------------------------- 接收数据预处理 --------------------------
		/* RxAlign=7 数据可能会丢失,在位位置 7、15、23、31、39(CollPos) 
		 * 		检测到的位冲突不能通过 RxAlign 解决,需要软件来实现
		 */
		if(ucBits == 7){
			// xxxx xxx?  ---- ---[x]  ==> 3 bytes!
			if( (MfComData.MfLength%8)==0 ){
				MfComData.mfcurrent += 1;
			}
			
            dummyShift1 = 0x00;								// reorder received bits
			/*
			 *	软件实现 RxAlign=7 时接收数据的移位恢复
			 *		xxxx xxx?  ---- ---[x] **** ***[-]  0000 000[*]
			 *		?000 0000  [x]xxx xxxx [-]--- ----  [*]*** ****
			 */
			if( MfComData.MfData[0] ){
				for (i=1; i<MfComData.mfcurrent; i++){		// MfData[0] keeps the CollPos	
					dummyShift2 = MfComData.MfData[i];
					/*
					 *	xxxx xxx?(>>1) 			==> 0xxx xxxx
					 *	---- ---[x](<<7) 		==> [x]00 0000
					 *	0xxx xxxx | [x]00 0000 	==> [x]xxx xxxx
					 */
					MfComData.MfData[i] = (dummyShift1 >> 1) | (MfComData.MfData[i] << 7);
					dummyShift1 = dummyShift2;
				}
            
				//MfComData.MfLength -= MfComData.mfcurrent;	// no need to update bits&bytes
				
				// recalculation of collision position
				//MfComData.MfData[0] += 7 - (MfComData.MfData[0] + 6) / 9;
			} // end of if( MfComData.MfData[0] )
			else{
				for (i=0; i<MfComData.mfcurrent; i++){	
					dummyShift2 = MfComData.MfData[i];
					MfComData.MfData[i] = (dummyShift1 >> 1) | (MfComData.MfData[i] << 7);
					dummyShift1 = dummyShift2;
				}
			}
        } // end of if(ucBits == 7)
	
		
		// -------------------------- 更新当前 UID 信息 --------------------------
	    ucTemp = ucSnr[(ucCollPosition / 8)];
		// MI_COLLERR/MI_OK, no other occured
	    if(status == MI_COLLERR){
			for (i=0; i < MfComData.mfcurrent; i++){// MfData[0] keeps the CollPos	
		         ucSnr[i + (ucCollPosition / 8)] = MfComData.MfData[i+1];
            }
	        ucSnr[(ucCollPosition / 8)] |= ucTemp;
			
	        ucCollPosition += MfComData.MfData[0];				// Update the ucCollPosition
			#ifdef __ANTICOLL_LOOP_DEBUG__
			USART_TransmitOne(0xbc);
			USART_TransmitOne(ucCollPosition);
			#endif
        }
        else if(status == MI_OK){
            for (i=0; i < MfComData.mfcurrent; i++){
                 ucSnr[4 - i] = MfComData.MfData[MfComData.mfcurrent - i - 1];
            }
            ucSnr[(ucCollPosition / 8)] |= ucTemp;
        }
    } while(status == MI_COLLERR);
Beispiel #19
0
/////////////////////////////////////////////////////////////////////
//功    能:通过RC522和ISO14443卡通讯
//参数说明:Command[IN]:RC522命令字
//          pInData[IN]:通过RC522发送到卡片的数据
//          InLenByte[IN]:发送数据的字节长度
//          pOutData[OUT]:接收到的卡片返回数据
//          *pOutLenBit[OUT]:返回数据的位长度
/////////////////////////////////////////////////////////////////////
char PcdComMF522(unsigned char Command, 
                 unsigned char *pInData, 
                 unsigned char InLenByte,
                 unsigned char *pOutData, 
                 unsigned int  *pOutLenBit)
{
    char status = MI_ERR;
    unsigned char irqEn   = 0x00;
    unsigned char waitFor = 0x00;
    unsigned char lastBits;
    unsigned char n;
    unsigned int i;
    switch (Command)
    {
       case PCD_AUTHENT:
          irqEn   = 0x12;
          waitFor = 0x10;
          break;
       case PCD_TRANSCEIVE:
          irqEn   = 0x77;
          waitFor = 0x30;
          break;
       default:
         break;
    }
   
    WriteRawRC(ComIEnReg,irqEn|0x80);
    ClearBitMask(ComIrqReg,0x80);
    WriteRawRC(CommandReg,PCD_IDLE);
    SetBitMask(FIFOLevelReg,0x80);
    
    for (i=0; i<InLenByte; i++)
    {   WriteRawRC(FIFODataReg, pInData[i]);    }
    WriteRawRC(CommandReg, Command);
   
    
    if (Command == PCD_TRANSCEIVE)
    {    SetBitMask(BitFramingReg,0x80);  }
    
    i = 600;//根据时钟频率调整,操作M1卡最大等待时间25ms
    do 
    {
         n = ReadRawRC(ComIrqReg);
         i--;
    }
    while ((i!=0) && !(n&0x01) && !(n&waitFor));
    ClearBitMask(BitFramingReg,0x80);
	      
    if (i!=0)
    {    
         if(!(ReadRawRC(ErrorReg)&0x1B))
         {
             status = MI_OK;
             if (n & irqEn & 0x01)
             {   status = MI_NOTAGERR;   }
             if (Command == PCD_TRANSCEIVE)
             {
               	n = ReadRawRC(FIFOLevelReg);
              	lastBits = ReadRawRC(ControlReg) & 0x07;
                if (lastBits)
                {   *pOutLenBit = (n-1)*8 + lastBits;   }
                else
                {   *pOutLenBit = n*8;   }
                if (n == 0)
                {   n = 1;    }
                if (n > MAXRLEN)
                {   n = MAXRLEN;   }
                for (i=0; i<n; i++)
                {   pOutData[i] = ReadRawRC(FIFODataReg);    }
            }
         }
         else
         {   status = MI_ERR;   }
        
   }
   

   SetBitMask(ControlReg,0x80);           // stop timer now
   WriteRawRC(CommandReg,PCD_IDLE); 
   return status;
}
Beispiel #20
0
bool MFRC522::PcdComPicc(unsigned char Command,unsigned char *pDataToPicc,unsigned char toPiccLength,
	                                       unsigned char *pDataInPcd, unsigned int  *pInBitLength)
{
    bool status = false;
    unsigned char irqEn   = 0x00;
    unsigned char waitFor = 0x00;
    unsigned char lastBits;
    unsigned char n;
    unsigned int i;
	char temp;
    switch (Command)
    {
       case MFRC522_PCD_AUTHENT:
          irqEn   = 0x12;
          waitFor = 0x10;
          break;
       case MFRC522_PCD_TRANSCEIVE:
          irqEn   = 0x77;
          waitFor = 0x30;
          break;
       default:
         break;
    }
 
    WriteRawRC(MFRC522_ComIEnReg,irqEn|0x80);//管脚IRQ上的信号与寄存器StatusReg的IRQ位的值相反
    ClearBitMask(MFRC522_ComIrqReg,0x80);    //中断标志,定义CommIRqReg寄存器中的屏蔽位置位
    WriteRawRC(MFRC522_CommandReg,MFRC522_PCD_IDLE);//设置为IDLE状态(模拟电路开启,MFR522唤醒,取消当前命令的执行,命令为0)
    SetBitMask(MFRC522_FIFOLevelReg,0x80);          //清FIFO状态标志和错误标志,FIFO计数清零
    
    for (i=0; i<toPiccLength; i++)
    	WriteRawRC(MFRC522_FIFODataReg, pDataToPicc[i]);
    WriteRawRC(MFRC522_CommandReg, Command);
   
    
    if (Command == MFRC522_PCD_TRANSCEIVE)
       SetBitMask(MFRC522_BitFramingReg,0x80);//启动数据发送
    
    i = 0;//操作M1卡最大等待时间25ms
	double timeOut=tskmgr.Time();
    do 
    {
		if(tskmgr.Time()-timeOut > 0.027)
		{
			i=1;//超时
			break;
		}
		n = ReadRawRC(MFRC522_ComIrqReg);//获取中断标志寄存器
		}while (!(n&0x01) && !(n&waitFor));//等待传输完成,并且定时器的值递减到零时退出
    ClearBitMask(MFRC522_BitFramingReg,0x80);//清掉启动数据发送位
	      
    if (i==0)//没有超时
    {    
		temp=(ReadRawRC(MFRC522_ErrorReg));
         if(!(temp&0x1B))
         {
             status = true;
             if (n & irqEn & 0x01)
                status = false;
             if (Command == MFRC522_PCD_TRANSCEIVE)
             {
				n = ReadRawRC(MFRC522_FIFOLevelReg);//获取FIFO中数据的长度
				lastBits = ReadRawRC(MFRC522_ControlReg) & 0x07;//最后接收到的字节的有效位数,为零时整个字节有效

				if (lastBits)
					*pInBitLength = (n-1)*8 + lastBits;
				else
					*pInBitLength = n*8;

				if (n == 0)//队列中没有数据
					n = 1;

				if (n > MFRC522_MaxReceiveLen)//长度超过了最大长度
					n = MFRC522_MaxReceiveLen;

				for (i=0; i<n; i++)
					pDataInPcd[i] = ReadRawRC(MFRC522_FIFODataReg);
            }
         }
         else//出错
            status = false;
   }
   

   SetBitMask(MFRC522_ControlReg,0x80);           // stop timer now
   WriteRawRC(MFRC522_CommandReg,MFRC522_PCD_IDLE); //取消当前命令的执行
  
   return status;
}
Beispiel #21
0
/////////////////////////////////////////////////////////////////////
//功    能:清RC522寄存器位
//参数说明:reg[IN]:寄存器地址
//          mask[IN]:清位值
/////////////////////////////////////////////////////////////////////
void ClearBitMask(unsigned char reg,unsigned char mask)  
{
    char tmp = 0x0;
    tmp = ReadRawRC(reg);
    WriteRawRC(reg, tmp & ~mask);  // clear bit mask
} 
Beispiel #22
0
/////////////////////////////////////////////////////////////////////
//功    能:置RC522寄存器位
//参数说明:reg[IN]:寄存器地址
//          mask[IN]:置位值
/////////////////////////////////////////////////////////////////////
void SetBitMask(unsigned char reg,unsigned char mask)  
{
    char tmp = 0x0;
    tmp = ReadRawRC(reg);
    WriteRawRC(reg,tmp | mask);  // set bit mask
}
Beispiel #23
0
char PcdComMF522(uint8_t   Command,
		uint8_t *pIn ,
		uint8_t   InLenByte,
		uint8_t *pOut ,
		uint8_t *pOutLenBit)
{
	FUNCTION() ;
	char   status = TAG_ERR;
	uint8_t   irqEn   = 0x00;
	uint8_t   waitFor = 0x00;
	uint8_t   lastBits;
	uint8_t   n;
	uint32_t   i;
	uint8_t PcdErr;

	//	printf("CMD %02x\n",pIn[0]);
	switch (Command)
	{
	case PCD_AUTHENT:
		irqEn   = 0x12;
		waitFor = 0x10;
		break;
	case PCD_TRANSCEIVE:
		irqEn   = 0x77;
		waitFor = 0x30;
		break;
	default:
		break;
	}

	WriteRawRC(ComIEnReg,irqEn|0x80);
	//	WriteRawRC(ComIEnReg,irqEn);
	ClearBitMask(ComIrqReg,0x80);
	SetBitMask(FIFOLevelReg,0x80);
	WriteRawRC(CommandReg,PCD_IDLE);

	for (i=0; i<InLenByte; i++) {
		WriteRawRC(FIFODataReg, pIn [i]);
	}

	WriteRawRC(CommandReg, Command);

	if (Command == PCD_TRANSCEIVE) {
		SetBitMask(BitFramingReg,0x80);
	}

	//i = 600;//���ʱ��Ƶ�ʵ������M1�����ȴ�ʱ��25ms
	i = 150;
	do
	{
		usleep(200);
		//		bcm2835_delayMicroseconds(200);
		n = ReadRawRC(ComIrqReg);
		i--;
	}
	while ((i!=0) && (!(n&0x01)) && (!(n&waitFor)));

	ClearBitMask(BitFramingReg,0x80);

	if (i!=0)
	{
		PcdErr=ReadRawRC(ErrorReg);
		if (!(PcdErr & 0x11))
		{
			status = TAG_OK;
			if (n & irqEn & 0x01) {status = TAG_NOTAG;}
			if (Command == PCD_TRANSCEIVE) {
				n = ReadRawRC(FIFOLevelReg);
				lastBits = ReadRawRC(ControlReg) & 0x07;
				if (lastBits) {*pOutLenBit = (n-1)*8 + lastBits;}
				else {*pOutLenBit = n*8;}

				if (n == 0) {n = 1;}
				if (n > MAXRLEN) {n = MAXRLEN;}

				for (i=0; i<n; i++) {
					pOut [i] = ReadRawRC(FIFODataReg);
//					printf (".%02X ",pOut[i]);
				}
			}
		}
		else {
			//			fprintf (stderr,"Err %02x\n",PcdErr);
			status = TAG_ERR;}

		if (PcdErr&0x08) {
			if (debug) fprintf (stderr,"COllision \n");
			status = TAG_COLLISION;

		}

	}


	//    SetBitMask(ControlReg,0x80);           // stop timer now
	//    WriteRawRC(CommandReg,PCD_IDLE); ???????
//	printf ("PCD Err %02x\n",PcdErr);
	return status;
}
Beispiel #24
0
char PcdReset(void)
{
	WriteRawRC(CommandReg,PCD_RESETPHASE);
	usleep(10000);
	ClearBitMask(TxControlReg,0x03);
	usleep(10000);
	SetBitMask(TxControlReg,0x03);
	WriteRawRC(TModeReg,0x8D);
	WriteRawRC(TPrescalerReg,0x3E);
	WriteRawRC(TReloadRegL,30);
	WriteRawRC(TReloadRegH,0);
	WriteRawRC(TxASKReg,0x40);
	WriteRawRC(ModeReg,0x3D);            //6363
	//	WriteRawRC(DivlEnReg,0x90);
	WriteRawRC(RxThresholdReg,0x84);
	WriteRawRC(RFCfgReg,0x68);
	WriteRawRC(GsNReg,0xff);
	WriteRawRC(CWGsCfgReg,0x2f);
	//	WriteRawRC(ModWidthReg,0x2f);

	return TAG_OK;
}
Beispiel #25
0
char PcdReset(void)
{
	uint8_t i = 0;

	FUNCTION() ;
	i = ReadRawRC(ComIEnReg);
	printf("before soft reset   0x02 address value is 0x%x\n",i);
	WriteRawRC(CommandReg,PCD_RESETPHASE);
	usleep(10000);
// this is by myself
	i = ReadRawRC(ComIEnReg);
	if (i == 0x80) {
		printf("read success  and after reset 0x02 value is 0x%x\n",i);
	}else {
		printf("after reset 0x02 value is 0x%x , not is 0x80",i);
	}
#if 0
	i &= 0x0F;
	
	if(i == PCD_IDLE) {
		printf("now a20 tran cancle command : 0x%x \n",PCD_IDLE);
	}else if(i == PCD_AUTHENT) {
		printf("now a20 tran authent command : 0x%x\n",PCD_AUTHENT);
	}else if(i == PCD_RECEIVE) {
		printf("now a20 tran receive command : 0x%x\n",PCD_RECEIVE);
	}else if(i == PCD_TRANSMIT) {
		printf("now a20 tran transmit command : 0x%x\n",PCD_TRANSMIT);
	}else if(i == PCD_RESETPHASE) {
		printf("now a20 tran so_reset command : 0x%x\n",PCD_RESETPHASE);
	}else if(i == PCD_CALCCRC) {
		printf("now a20 tran calccrc command: 0x%x\n",PCD_CALCCRC);
	}else {
		printf("unkonw a20 command,check spi read/write code\n");
	}

#endif

#if 1

	ClearBitMask(TxControlReg,0x03);
	usleep(10000);

	SetBitMask(TxControlReg,0x03);
	WriteRawRC(TModeReg,0x8D);
	WriteRawRC(TPrescalerReg,0x3E);
	WriteRawRC(TReloadRegL,30);
	WriteRawRC(TReloadRegH,0);
	WriteRawRC(TxASKReg,0x40);
	WriteRawRC(ModeReg,0x3D);            //6363
	//	WriteRawRC(DivlEnReg,0x90);
	WriteRawRC(RxThresholdReg,0x84);
	WriteRawRC(RFCfgReg,0x68);
	WriteRawRC(GsNReg,0xff);
	WriteRawRC(CWGsCfgReg,0x2f);
	//	WriteRawRC(ModWidthReg,0x2f);
#endif
	return TAG_OK;
}
Beispiel #26
0
/////////////////////////////////////////////////////////////////////
//功    能:清RC522寄存器位
//参数说明:reg[IN]:寄存器地址
//          mask[IN]:清位值
/////////////////////////////////////////////////////////////////////
void ClearBitMask(u8   reg,u8   mask)  
{
    char   tmp = 0x0;
    tmp = ReadRawRC(reg);
    WriteRawRC(reg, tmp & ~mask);  // clear bit mask
} 
Beispiel #27
0
/////////////////////////////////////////////////////////////////////
//功    能:置RC522寄存器位
//参数说明:reg[IN]:寄存器地址
//          mask[IN]:置位值
/////////////////////////////////////////////////////////////////////
void SetBitMask(u8   reg,u8   mask)  
{
    char   tmp = 0x0;
    tmp = ReadRawRC(reg);
    WriteRawRC(reg,tmp | mask);  // set bit mask
}