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; }
void ClearBitMask(uint8_t reg,uint8_t mask) { FUNCTION() ; char tmp = 0x0; tmp = ReadRawRC(reg); WriteRawRC(reg, tmp & ~mask); // clear bit mask }
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 }
void MFRC522::PcdAntennaOn() { unsigned char i; i = ReadRawRC(MFRC522_TxControlReg); if (!(i & 0x03)) { SetBitMask(MFRC522_TxControlReg, 0x03); } }
///////////////////////////////////////////////////////////////////// //开启天线 //每次启动或关闭天险发射之间应至少有1ms的间隔 ///////////////////////////////////////////////////////////////////// void PcdAntennaOn() { unsigned char i; i = ReadRawRC(TxControlReg); if (!(i & 0x03)) { SetBitMask(TxControlReg, 0x03); } }
///////////////////////////////////////////////////////////////////// //开启天线 //每次启动或关闭天险发射之间应至少有1ms的间隔 ///////////////////////////////////////////////////////////////////// void PcdAntennaOn(void) { u8 i; i = ReadRawRC(TxControlReg); if (!(i & 0x03)) { SetBitMask(TxControlReg, 0x03); } }
///////////////////////////////////////////////////////////////////// //用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); }
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); }
void PcdAntennaOn(void) { FUNCTION() ; uint8_t i; i = ReadRawRC(TxControlReg); // printf("PCdAntennaON i = 0x%x !!!!!!!!!!!!!!!!!!!! by jason\n",i); if (!(i & 0x03)) { SetBitMask(TxControlReg, 0x03); //printf("set antenna again !!!!! by jason \n"); } // i = ReadRawRC(TxControlReg); //printf("in function PcdAntennaOn i = %x ------------> by jason\n",i); //if((i & 0x03) != 0x03) { //printf("tian xian open faild !\n"); //} }
char PcdAuthState(uint8_t auth_mode,uint8_t addr,uint8_t *pKey,uint8_t *pSnr) { char status; uint8_t unLen; uint8_t ucComMF522Buf[MAXRLEN]; ucComMF522Buf[0] = auth_mode; ucComMF522Buf[1] = addr; memcpy(&ucComMF522Buf[2], pKey, 6); memcpy(&ucComMF522Buf[8], pSnr, 4); status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen); if ((status != TAG_OK) || (!(ReadRawRC(Status2Reg) & 0x08))) { status = TAG_ERR; } return status; }
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; }
///////////////////////////////////////////////////////////////////// //功 能:验证卡片密码 //参数说明: auth_mode[IN]: 密码验证模式 // 0x60 = 验证A密钥 // 0x61 = 验证B密钥 // addr[IN]:块地址 // pKey[IN]:密码 // pSnr[IN]:卡片序列号,4字节 //返 回: 成功返回MI_OK ///////////////////////////////////////////////////////////////////// char PcdAuthState(unsigned char auth_mode,unsigned char addr,unsigned char *pKey,unsigned char *pSnr) { char status; unsigned int unLen; unsigned char i,ucComMF522Buf[MAXRLEN]; ucComMF522Buf[0] = auth_mode; ucComMF522Buf[1] = addr; for (i=0; i<6; i++) { ucComMF522Buf[i+2] = *(pKey+i); } for (i=0; i<6; i++) { ucComMF522Buf[i+8] = *(pSnr+i); } status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen); if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08))) { status = MI_ERR; } return status; }
///////////////////////////////////////////////////////////////////// //功 能:验证卡片密码 //参数说明: auth_mode[IN]: 密码验证模式 // 0x60 = 验证A密钥 // 0x61 = 验证B密钥 // addr[IN]:块地址 // pKey[IN]:密码 // pSnr[IN]:卡片序列号,4字节 //返 回: 成功返回MI_OK ///////////////////////////////////////////////////////////////////// char PcdAuthState(u8 auth_mode,u8 addr,u8 *pKey,u8 *pSnr) { char status; u8 unLen; u8 i,ucComMF522Buf[MAXRLEN]; ucComMF522Buf[0] = auth_mode; ucComMF522Buf[1] = addr; // for (i=0; i<6; i++) // { ucComMF522Buf[i+2] = *(pKey+i); } // for (i=0; i<6; i++) // { ucComMF522Buf[i+8] = *(pSnr+i); } memcpy(&ucComMF522Buf[2], pKey, 6); memcpy(&ucComMF522Buf[8], pSnr, 4); status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen); if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08))) { status = MI_ERR; } return status; }
//////////////////////// ///验证卡片密码 ///@param auth_mode 验证密码模式 取值: /// MFRC522_PICC_AUTHENT1A 验证A密匙 /// MFRC522_PICC_AUTHENT1B 验证B密匙 ///@param addr 块地址 ///@param pKey 密码,6个字节 ///@param pSnr 卡片序列号,4字节 //////////////////////// bool MFRC522::PcdAuthState(unsigned char auth_mode,unsigned char addr, unsigned char *pKey,unsigned char *pSnr) { char status; unsigned int unLen; unsigned char i,ucComMF522Buf[MFRC522_MaxReceiveLen]; ucComMF522Buf[0] = auth_mode; ucComMF522Buf[1] = addr; for (i=0; i<6; i++) { ucComMF522Buf[i+2] = *(pKey+i); } for (i=0; i<6; i++) { ucComMF522Buf[i+8] = *(pSnr+i); } // memcpy(&ucComMF522Buf[2], pKey, 6); // memcpy(&ucComMF522Buf[8], pSnr, 4); status = PcdComPicc(MFRC522_PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen); if (!status || (!(ReadRawRC(MFRC522_Status2Reg) & 0x08))) { status = false; } return status; }
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; }
///////////////////////////////////////////////////////////////////// //功 能:通过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; }
///////////////////////////////////////////////////////////////////// //功 能:清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 }
///////////////////////////////////////////////////////////////////// //功 能:置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 }
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; }
///////////////////////////////////////////////////////////////////// //功 能:清RC522寄存器位 //参数说明:reg[IN]:寄存器地址 // mask[IN]:清位值 ///////////////////////////////////////////////////////////////////// void ClearBitMask(u8 reg,u8 mask) { char tmp = 0x0; tmp = ReadRawRC(reg); WriteRawRC(reg, tmp & ~mask); // clear bit mask }
///////////////////////////////////////////////////////////////////// //功 能:置RC522寄存器位 //参数说明:reg[IN]:寄存器地址 // mask[IN]:置位值 ///////////////////////////////////////////////////////////////////// void SetBitMask(u8 reg,u8 mask) { char tmp = 0x0; tmp = ReadRawRC(reg); WriteRawRC(reg,tmp | mask); // set bit mask }