Ejemplo n.º 1
0
/**************************************************************************************************
 * @fn          MFRC522_CrcCheck
 * @brief       用MF522计算CRC校验
 * @param       CrcData   -> 要校验CRC的数据
                CrcLen    -> 数据长度
                CheckData -> CRC校验结果  
 * @return      Size -> 卡号容量 
 **************************************************************************************************
 */
void MFRC522_CrcCheck(uint8_t *CrcData, uint8_t CrcLen, uint8_t *CheckData)
{
  uint8_t i;
  uint8_t CrcIrq;
  
  MFRC522_ClearBitMask(DivIrqReg,0x04);     //BIT2=CRCIrq(0)
  MFRC522_SetBitMask(FIFOLevelReg,0x80);    //BIT7=FlushBuffer(1), FIFO初始化
  
  /*1.向FIFO中写入数据*/
  for(i=0; i<CrcLen; i++)
  {
    MFRC522_Write(FIFODataReg,CrcData[i]);
  }
  MFRC522_Write(CommandReg,PCD_CALCCRC);    //激活CRC协处理器或执行自测试
  
  /*2.等待CRC校验完成*/
  i = 0xFF;
  do
  {
    CrcIrq = MFRC522_Read(DivIrqReg);       //BIT2=CRCIrq,CRC协处理器在处理完FIFO缓冲区的所有数据后置位CRCIRq标志
    i--;
  }
  while((i!=0)&&!(CrcIrq & 0x04));          //1)i=0超时跳出 2)处理完FIFO缓冲区的所有数据跳出
  
  /*3.读取CRC校验结果*/
  CheckData[0] = MFRC522_Read(CRCResultRegL); 
  CheckData[1] = MFRC522_Read(CRCResultRegM);
  
}
Ejemplo n.º 2
0
/**************************************************************************************************
 * @fn          MFRC522_ConfigISOType
 * @brief       设置RC632的工作方式,ISO14443A协议标准
 * @param       无
 * @return      无
 **************************************************************************************************
 */
void MFRC522_ISO14443A(void)
{
   MFRC522_SetBitMask(Status2Reg, 0x08); //该位用来指示MIFARE Cypto1单元接通和因此所有卡的数据通信被加密的情况,MFCrypto1On=0
   MFRC522_Write(RxSelReg , 0x86);       //84 非接触式UART的输入选择内部模拟部分的调制信号
   MFRC522_Write(RFCfgReg , 0x7F);       //4F 接收器信号电压的增益因子48dB
   MFRC522_Delay(1);
   MFRC522_AntennaOn();
}
Ejemplo n.º 3
0
/**************************************************************************************************
 * @fn          MFRC522_Anticoll
 * @brief       RC522和ISO14443卡通讯
 * @param       CardData  -> 卡号数据
 * @return      ReqStatus -> 寻卡结果 
 **************************************************************************************************
 */
uint8_t MFRC522_Anticoll(uint8_t *CardData)
{
  uint8_t i;
  uint8_t AntiStatus = MFRC522_ERR;
  uint32_t AntiBits;    //接收到的数据有效位数
  uint8_t CardDataCheck = 0;

  MFRC522_ClearBitMask(Status2Reg,0x08);  //关闭内部温度传感器
  MFRC522_Write(BitFramingReg,0x00);      //BIT2-BIT0=TxLastBists(000)  定义发送的最后一个字节的位数,000表示最后一个字节的所有位都应发送
  MFRC522_ClearBitMask(CollReg,0x80);     //BIT7=ValuesAfterColl(1) 
  
  CardData[0] = PICC_ANTICOLL;
  CardData[1] = 0x20;
  
  AntiStatus = MFRC522_ToCard(PCD_TRANSCEIVE,CardData,2,CardData,&AntiBits);
  
  if(AntiStatus == MFRC522_OK)
  {
    /*校验卡号*/
    for(i=0; i<4; i++)
    {
      CardDataCheck ^= CardData[i];      //1.datasheet/RFID/MifareCard/1.M1简单介绍,4byte卡号 1byte校验字
    }
    
    if(CardDataCheck != CardData[i])
    {
      AntiStatus = MFRC522_ERR;
    }
  }
  
  MFRC522_SetBitMask(CollReg,0x80);      //BIT7=ValuesAfterColl(1) 
  return AntiStatus;
}
Ejemplo n.º 4
0
uint8_t MFRC522_RequestCard(uint8_t ReqMode,uint8_t *CardType)
{   
  uint8_t ReqStatus = MFRC522_ERR;  
  uint32_t ReqBits;   //接收到的数据有效位数
  
  MFRC522_Write(BitFramingReg,0x07);  //BIT2-BIT0=TxLastBists(111)?
  //ReqStatus = MFRC522_Read(BitFramingReg);
  
  CardType[0] = ReqMode;
  
  ReqStatus = MFRC522_ToCard(PCD_TRANSCEIVE, CardType, 1, CardType, &ReqBits);
  
  if((ReqStatus != MFRC522_OK)||(ReqBits != 0x10))       //如果返回的不是16bit 0x0400正好是16bit
  {
    ReqStatus = MFRC522_ERR;
  }
  
  return ReqStatus; 
}
Ejemplo n.º 5
0
/**************************************************************************************************
 * @fn          MFRC522_Reset
 * @brief       MFRC522复位阶段设置
 * @param       n
 * @return      无
 **************************************************************************************************
 */
void MFRC522_Reset(void)
{
  MFRC522_RST = 1;    
  MFRC522_Delay(1);
  MFRC522_RST = 0;    //低电平时切断内部电流吸收,关闭振荡器,断开输入管脚与外部电路的连接
  MFRC522_Delay(1);   
  MFRC522_RST = 1;    //上升沿来启动内部复位阶段
  MFRC522_Delay(1);
  
  MFRC522_Write(CommandReg, PCD_RESETPHASE);  //BIT4=PowerDown(0):启动唤醒过程 BIT3-BIT0(1111):复位MFRC522
  

  /*TPrescaler 12位预分频器 110100111110(3390)**/
  MFRC522_Write(TModeReg,0x8D);               //BIT7=TAuto(1):定时器启动  BIT3-BIT0=TPrescaler_Hi(1101):预分频器高4位
  MFRC522_Write(TPrescalerReg,0x3E);          //BIT7-BIT0(00111110)=TPrescaler_Lo:定时器预分频器低8位
  /*TreloadVal 16位定时器重装值 30*/
  MFRC522_Write(TReloadRegL,0x30);            //定时器频率f = 6.78Mhz/TPrescaler  T = 1/f = TPrescaler/6.78Mhz
  MFRC522_Write(TReloadRegH,0);               //t = TreloadVal * T =  15ms   如果要为24ms,TReloadRegL = 0x30
  
  MFRC522_Write(ModeReg, 0x3D);               //BIT1-BIT0=CRCPreset(01):6363
  MFRC522_Write(TxAutoReg, 0x40);	      //100%ASK
}
Ejemplo n.º 6
0
/**************************************************************************************************
 * @fn          MFRC522_SetBitMask
 * @brief       清RC522寄存器位
 * @param       RegAddr   -> 寄存器地址
                Mask      -> 置位值
 * @return      无
 **************************************************************************************************
 */
void MFRC522_SetBitMask(uint8_t RegAddr,uint8_t Mask)
{
  uint8_t tmp;
  tmp = MFRC522_Read(RegAddr);
  MFRC522_Write(RegAddr, tmp | Mask);
}
Ejemplo n.º 7
0
/**************************************************************************************************
 * @fn          MFRC522_ClearBitMask
 * @brief       清RC522寄存器位
 * @param       RegAddr   -> 寄存器地址
                Mask      -> 清位值
 * @return      无
 **************************************************************************************************
 */
void MFRC522_ClearBitMask(uint8_t RegAddr,uint8_t Mask)
{
  uint8_t tmp;
  tmp = MFRC522_Read(RegAddr);
  MFRC522_Write(RegAddr, tmp&(~Mask));
}
Ejemplo n.º 8
0
/**************************************************************************************************
 * @fn          MFRC522_ToCard
 * @brief       RC522和ISO14443卡通讯
 * @param       Command       ->  MF522命令字
                SendData      ->  过RC522发送到卡片的数据,
                SendLen       ->  发送的数据长度
                ReceiveData   ->  接收到的卡片返回数据
                ReveiveLen    ->  返回数据的位长度
 * @return      ReqStatus     ->  寻卡结果 
 **************************************************************************************************
 */
uint8_t MFRC522_ToCard(uint8_t Command, uint8_t *SendData, uint8_t SendLen, uint8_t *ReceiveData, uint32_t *ReveiveBits)
{
  uint8_t Status  = MFRC522_ERR; 
  uint8_t IrqEn   = 0x00;
  uint8_t WaitIrq = 0x00; 
  uint32_t i;
  uint8_t IRqStatus;
  uint8_t FIFOLevel  = 0x00;       //FIFOLevelReg BIT6-BIT0 FIFO缓冲区中保存的字节数,BIT7被读时返回为0无须担心
  uint8_t RxLastBits = 0x00;        //ControlReg   BIT2-BIT0 显示最后接收到的字节的有效位数目,如果该位为0,整个字节有效 
    
  switch(Command)
  {
    case PCD_AUTHENT:     IrqEn   = 0x12;    //认证卡密
                          WaitIrq = 0x10;
                          break;
                      
    case PCD_TRANSCEIVE:  IrqEn   = 0x77;    //发送FIFO中数据
                          WaitIrq = 0x30;
                          break;
                        
    default:              break;
  }
  
  MFRC522_Write(CommIEnReg, IrqEn|0x80);     //允许中断请求
  MFRC522_ClearBitMask(CommIrqReg, 0x80);    //清除所有中断请求位
  MFRC522_SetBitMask(FIFOLevelReg, 0x80);    //BIT7=FlushBuffer(1), FIFO初始化
  MFRC522_Write(CommandReg, PCD_IDLE);       //无动作,取消当前动作的执行
  
  /*1.向FIFO中写入数据*/
  for(i=0; i<SendLen; i++)
  {
    MFRC522_Write(FIFODataReg,SendData[i]);
  }
  
  /*2.执行发送命令,将FIFO缓冲区的数据发送到天线,发送完成后自动激活接收器*/
  MFRC522_Write(CommandReg,Command);
  if((Command == PCD_TRANSCEIVE) ||(Command == PCD_AUTHENT))               
  { 
    MFRC522_SetBitMask(BitFramingReg,0x80);   //BIT7=StartSend(1):启动数据发送
  }
  
  /*3.等待数据接收完成*/
  i = 2000;                                   //i根据时钟频率调整,操作M1卡最大等待时间15ms?注意上面MFRC522_Reset函数中定时器的设置时间是15ms
  do
  {
    IRqStatus = MFRC522_Read(CommIrqReg);
    i--;
  }
  while((i!=0)&& !(IRqStatus&0x01) && !(IRqStatus&WaitIrq)); //1)i=0超时跳出 2)定时器(15ms)减到0时跳出 3)命令终止或者接收完成跳出
  MFRC522_ClearBitMask(BitFramingReg,0x80);   //停止数据发送
  
  
  /*4.检测寻卡状态*/
  if(i != 0)
  {
    /*4.1.寻卡未发生错误*/
    if(!(MFRC522_Read(ErrorReg) & 0x1B))      //未发生以下错误:BufferOvfl Collerr CRCErr ProtecolErr
    {
      Status = MFRC522_OK;                    //这里可以设一个断点查看,表明未发生错误
      
      if(IRqStatus & IrqEn & 0x01)            //定时器递减到零,寻卡超时
      {
        Status = MFRC522_TIMEOUT;              
      }
      
       /*4.1.1 接收到的数据处理*/
      if(Command == PCD_TRANSCEIVE)                     
      {
         FIFOLevel  = MFRC522_Read(FIFOLevelReg);       //接收到的字节数
         RxLastBits = MFRC522_Read(ControlReg) & 0x07;  //最后一个字节的有效数
         
         if(RxLastBits)                                 //如果不是0,最后一个字节并不是整个字节有效
         {
           *ReveiveBits = (FIFOLevel-1)*8 + RxLastBits;  
         }
         else                                           //如果是0,整个字节有效
         {
           *ReveiveBits = FIFOLevel * 8;
         }
         if(FIFOLevel == 0)
         {
           FIFOLevel = 1;
         }
         if(FIFOLevel > FIFOLEVEL_MAX)
         {
           FIFOLevel = FIFOLEVEL_MAX;
         }
         
         /*4.1.2 读取接收到的数据*/
         for(i=0; i<FIFOLevel; i++)
         {
           ReceiveData[i] = MFRC522_Read(FIFODataReg);    //读取FIFO缓冲区的数据
         }
      }
    }
    
    /*4.2.寻卡发生错误,错误类型未知*/
    else                                                  
    {
      Status = MFRC522_ERR;
    }
  }
  
  /*5.清除*/
  MFRC522_SetBitMask(ControlReg,0x80);  //停止定时器
  MFRC522_Write(CommandReg,PCD_IDLE);   //无动作,取消当前动作的执行
  
  return Status;
}
static int rc522_open(struct inode *inode, struct file *file)
{
	uint8_t str[MAX_LEN];
	uint8_t writeData[16]={1, 2, 3, 4, 0};
	uint8_t i;
	uint8_t status;
	uint8_t size;
	uint8_t blockAddr;	//选择操作的块地址0~63
	//扇区A密码,16个扇区,每个扇区密码6Byte
	uint8_t sectorKeyA[16][16] = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},};	

	printk("rc522_open\r\n");
	
	SPI_Init();
	MFRC522_Init();

	while (1)
	{
		//寻卡,返回卡类型	
		status = MFRC522_Request(PICC_REQIDL, str);	
		if (status == MI_OK)
		{
			printk("%d \r\n", str[0]);
			printk("%d \r\n", str[1]);
		}

		//防冲撞,返回卡的序列号 4字节
		status = MFRC522_Anticoll(str);
		memcpy(serNum, str, 5);
		if (status == MI_OK)
		{
			printk("%d \r\n", serNum[0]);
			printk("%d \r\n", serNum[1]);
			printk("%d \r\n", serNum[2]);
			printk("%d \r\n", serNum[3]);
			printk("%d \r\n", serNum[4]);
		}

		//选卡,返回卡容量
		size = MFRC522_SelectTag(serNum);
		if (size != 0)
		{
			printk("size is %d", size);
		}

		//写
		blockAddr = 1;		//数据块		
		status = MFRC522_Auth(PICC_AUTHENT1A, blockAddr, sectorKeyA[blockAddr/4], serNum);	//认证
		if (status == MI_OK)
		{
			//写数据
			status = MFRC522_Write(blockAddr, writeData);
		}

		//读
		blockAddr = 1;		//数据块		
		status = MFRC522_Auth(PICC_AUTHENT1A, blockAddr, sectorKeyA[blockAddr/4], serNum);	//认证
		if (status == MI_OK)
		{
			//读数据
			status = MFRC522_Read(blockAddr, str);
			if (status == MI_OK)
			{
				for (i=0; i<16; i++)
				{
					printk("%d ", str[i]);
				}
			}
		}

		MFRC522_Halt();			//命令卡片进入休眠状态*/
	}	
}