///////////////////////////////////////////////////////////////////// //功 能:复位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; }
/////////////////// ///防冲撞寻卡号 ///@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; }
void ClearBitMask(uint8_t reg,uint8_t mask) { FUNCTION() ; char tmp = 0x0; tmp = ReadRawRC(reg); WriteRawRC(reg, tmp & ~mask); // clear bit mask }
///////////////////////////////////////////////////////////////////// //功 能:防冲撞 //参数说明: 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; }
///////////////////////////////////////////////////////////////////// //功 能:寻卡 //参数说明: 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; }
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; }
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 }
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; }
///////////////////////////////////////////////////////////////////// //功 能:复位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; }
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); }
/** * @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; }
///////////////////////////////////////////////////////////////////// //用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 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; }
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; }
////////////////////////////////////////////////////////////////////// //设置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; }
///////////////////////////////////////////////////////////////////// //功 能:复位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; }
/** * @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);
///////////////////////////////////////////////////////////////////// //功 能:通过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; }
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寄存器位 //参数说明: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; }
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; }
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; }
///////////////////////////////////////////////////////////////////// //功 能:清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 }