#include "READER.h" #include "READER_REG.h" #include "LPCD_CFG.h" #include #include "ql_rtos.h" #include "ql_application.h" #include "ql_audio.h" #include "ql_iic.h" #include "ql_gpio.h" #include "app_inc.h" #include "ql_fs.h" unsigned char fm17622_i2c_no = 1; //CI2C match to twsi1 unsigned char ATQA[2]; unsigned char UID[8]; unsigned char UID_SIZE; unsigned char SAK[1]; void FM17622_WriteRawRC(uint8_t Address, uint8_t value) { ql_i2c_write(nfc_i2c_no, 0x50>>1, Address, &value, 1); } u8 DP1312EA_ReadRawRC(uint8_t Address) { u8 ucResult=0; ql_i2c_read(nfc_i2c_no, 0x50>>1, Address, &ucResult, 1); return ucResult; } void DelayUs( uint32_t xus ) { int t; while ( xus-- ) { t = 5; while ( t-- ) ; } } void DelayMs( uint32_t xms ) { DelayUs( xms * 1000 ); } unsigned char Reader_HardReset( void ) { NPD_0; // NPD = 0 DelayMs( 1 ); NPD_1; // NPD = 1 DelayMs( 10 ); return (SUCCESS); } unsigned char Reader_SoftReset( void ) { SetReg(JREG_COMMAND,CMD_SOFT_RESET); DelayMs( 10 ); return (SUCCESS); } unsigned char Reader_Set_HPD( unsigned char mode ) //mode = DISABLE 退出HPD模式 ,mode = ENABLE 进入HPD模式 { if ( mode == ENABLE ) { DelayMs( 1 ); //延时1ms NPD_0; // NPD = 0 } else { NPD_1; // NPD = 1 DelayMs( 1 ); //延时1ms,等待Reader启动 } return (mode); } void Reader_GPIO_Init( void ) { LL_GPIO_SetPinMode( NPD_GPIO, NPD_PIN, LL_GPIO_PINxMODE_OUTPUT ); LL_GPIO_SetPinMode(IRQ_GPIO,IRQ_PIN,LL_GPIO_PINxMODE_INPUT ); LL_GPIO_SetPinMode( SDA_GPIO, SDA_PIN, LL_GPIO_PINxMODE_OUTPUT ); // PB0 Digital function - I2C SDA LL_GPIO_EnablePinOpenDrain( SDA_GPIO, SDA_PIN ); LL_GPIO_EnablePinPullUp( SDA_GPIO, SDA_PIN ); LL_GPIO_SetPinMode( SCL_GPIO, SCL_PIN, LL_GPIO_PINxMODE_OUTPUT ); // PB2 Digital function - I2C SCL LL_GPIO_EnablePinOpenDrain( SCL_GPIO, SCL_PIN ); LL_GPIO_EnablePinPullUp( SCL_GPIO, SCL_PIN ); SCL_1; SDA_1; NPD_0; } unsigned char GetReg( unsigned char reg_address, unsigned char *reg_data ) { unsigned char i2c_address; i2c_address = I2C_ADDRESS; // u8 temp = 0; u16 err = 255; while ( temp == 0 ) //一直发送器件地址,直至唤醒器件为止 { //1.开始 I2C_START(); //2.设备地址、写 temp = I2C_Write_Byte( (i2c_address << 1) & 0xfe ); if ( --err == 0 ) { printf( "GetReg Error1\r\n" ); return (1); } } //3.寄存器地址 temp = I2C_Write_Byte( reg_address ); if ( temp == 0 ) { I2C_STOP(); printf( "GetReg Error2\r\n" ); return (0x2); } I2C_STOP(); //4.重新开始 temp = 0; err = 255; while ( temp == 0 ) { I2C_START(); //5.设备地址、读 temp = I2C_Write_Byte( (i2c_address << 1) | (I2C_Read) ); if ( --err == 0 ) { printf( "GetReg Error3\r\n" ); return (3); } } //6.读一字节数据 *reg_data = I2C_Read_Byte( 0 ); //7.停止 I2C_STOP(); return (SUCCESS); } unsigned char SetReg( unsigned char reg_address, unsigned char reg_data ) { unsigned char i2c_address; i2c_address = I2C_ADDRESS; // u8 temp = 0; u16 err = 255; while ( temp == 0 ) //一直发送器件地址,直至唤醒器件为止 { //1.开始start I2C_START(); //2.设备地址/写 //设备地址,EA=1,ADDR[6:0]=0xxxxxx,硬件定义;EA=0,0101XXX,低三位硬件定义 temp = I2C_Write_Byte( (i2c_address << 1) & 0xfe ); if ( --err == 0 ) { printf( "SetReg Error1\r\n" ); return (1); } } //3.数据地址 temp = I2C_Write_Byte( reg_address ); if ( temp == 0 ) { I2C_STOP(); //printf("SetReg Error2\r\n"); return (0x2); } //4.写一字节数据 temp = I2C_Write_Byte( reg_data ); if ( temp == 0 ) { I2C_STOP(); //printf("SetReg Error3\r\n"); return (0x3); } //5.停止 I2C_STOP(); I2C_DELAY( 2 ); return (SUCCESS); } //******************************************************* //函数名称:ModifyReg(unsigned char addr,unsigned char* mask,unsigned char set) //函数功能:写寄存器 //入口参数:addr:目标寄存器地址 mask:要改变的位 // set: 0:标志的位清零 其它:标志的位置起 //出口参数: //******************************************************** void ModifyReg( unsigned char reg_address, unsigned char mask, unsigned char set ) { unsigned char reg_data; GetReg( reg_address, ®_data ); if ( set ) { reg_data |= mask; } else { reg_data &= ~mask; } SetReg( reg_address, reg_data ); return; } //*********************************************** //函数名称:GetReg_Ext(unsigned char ExtRegAddr,unsigned char* ExtRegData) //函数功能:读取扩展寄存器值 //入口参数:ExtRegAddr:扩展寄存器地址 ExtRegData:读取的值 //出口参数:unsigned char TRUE:读取成功 FALSE:失败 //*********************************************** unsigned char GetReg_Ext( unsigned char ExtRegAddr, unsigned char* ExtRegData ) { SetReg( JREG_EXT_REG_ENTRANCE, JBIT_EXT_REG_RD_ADDR | ExtRegAddr ); GetReg( JREG_EXT_REG_ENTRANCE, &(*ExtRegData) ); return (SUCCESS); } //*********************************************** //函数名称:SetReg_Ext(unsigned char ExtRegAddr,unsigned char* ExtRegData) //函数功能:写扩展寄存器 //入口参数:ExtRegAddr:扩展寄存器地址 ExtRegData:要写入的值 //出口参数:unsigned char TRUE:写成功 FALSE:写失败 //*********************************************** unsigned char SetReg_Ext( unsigned char ExtRegAddr, unsigned char ExtRegData ) { //unsigned char t = 0; //GetReg_Ext( ExtRegAddr, &t ); //printf("1Get Ext reg %x, data %x\r\n", ExtRegAddr, t); //printf("1Set Ext reg %x, data %x\r\n", ExtRegAddr, ExtRegData); SetReg( JREG_EXT_REG_ENTRANCE, JBIT_EXT_REG_WR_ADDR | ExtRegAddr ); SetReg( JREG_EXT_REG_ENTRANCE, JBIT_EXT_REG_WR_DATA | ExtRegData ); //GetReg_Ext(ExtRegAddr, &t); //printf("2Get Ext reg %x, data %x\r\n\r\n", ExtRegAddr, t); return (SUCCESS); } //******************************************************* //函数名称:ModifyReg_Ext(unsigned char ExtRegAddr,unsigned char* mask,unsigned char set) //函数功能:寄存器位操作 //入口参数:ExtRegAddr:目标寄存器地址 mask:要改变的位 // set: 0:标志的位清零 其它:标志的位置起 //出口参数:unsigned char TRUE:写成功 FALSE:写失败 //******************************************************** void ModifyReg_Ext( unsigned char ExtRegAddr, unsigned char mask, unsigned char set ) { unsigned char regdata; GetReg_Ext( ExtRegAddr, ®data ); if ( set ) { regdata |= mask; } else { regdata &= ~(mask); } SetReg_Ext( ExtRegAddr, regdata ); return; } unsigned char Lpcd_Init_Register(void) { unsigned char reg_data; SetReg(JREG_COMMAND,0x20); GetReg(JREG_COMMAND,®_data); printf("JREG_COMMAND = %02X\r\n",reg_data); if(reg_data == 0x20) { SetReg_Ext(0x24, 0x14);//请勿修改 SetReg_Ext(0x25, 0x3A);//请勿修改 SetReg_Ext(JREG_LPCDCTRLMODE, (RF_DET_DISABLE|RF_DET_SEN_00|LPCD_ENABLE));//场检测使能,场检测灵敏度0,LPCD使能 SetReg_Ext(JREG_LPCDSLEEPTIMER, LPCD_SLEEPTIME);//设置LPCD休眠阶段时间 SetReg_Ext(JREG_LPCDRFTIMER, LPCD_IRQINV_ENABLE|LPCD_IRQ_PUSHPULL|LPCD_RFTIME_5us);//探测使用5us,LPCD探测总时间18us SetReg_Ext(JREG_LPCDTHRESH_L, LPCD_THRSH & 0x3F);//LPCD触发阈值低6位 SetReg_Ext(JREG_LPCDTHRESH_H, BIT5|BIT2|((LPCD_THRSH & 0xC0)>>6));//LPCD触发阈值高2位 SetReg_Ext(JREG_LPCDTXCTRL2, LPCD_CWP);//设置LPCD输出P驱动 SetReg_Ext(JREG_LPCDTXCTRL3, LPCD_CWN);//设置LPCD输出N驱动 SetReg_Ext(JREG_LPCDREQATIMER,LPCD_REQA_TIME_5ms);//REQA检测载波时间,5ms兼容手机方案 SetReg_Ext(JREG_LPCDREQAANA,LPCD_RXGAIN_33DB | LPCD_MINLEVEL_9 | LPCD_MODWIDTH_38);//配置REQA检测命令的接收增益,接收阈值,调制宽度 //SetReg_Ext(JREG_LPCDDETECTMODE,LPCD_TXSCALE_4|LPCD_COMBINE_MODE);//配置REQA检测发射功率与探测输出场强的比例,LCPD探测模式设置 SetReg_Ext(JREG_LPCDDETECTMODE, LPCD_TXSCALE_4|LPCD_RX_CHANGE_MODE); GetReg_Ext(0x24,®_data);//请勿修改 printf("0x24 = %02X\r\n",reg_data); GetReg_Ext(0x25,®_data);//请勿修改 printf("0x25 = %02X\r\n",reg_data); GetReg_Ext(JREG_LPCDCTRLMODE,®_data);//场检测使能,场检测灵敏度0,LPCD使能 printf("JREG_LPCDCTRLMODE = %02X\r\n",reg_data); GetReg_Ext(JREG_LPCDSLEEPTIMER,®_data);//设置LPCD休眠阶段时间 printf("JREG_LPCDSLEEPTIMER = %02X\r\n",reg_data); GetReg_Ext(JREG_LPCDRFTIMER,®_data);//探测使用5us,LPCD探测总时间18us printf("JREG_LPCDRFTIMER = %02X\r\n",reg_data); GetReg_Ext(JREG_LPCDTHRESH_L,®_data);//LPCD触发阈值低6位 printf("JREG_LPCDTHRESH_L = %02X\r\n",reg_data); GetReg_Ext(JREG_LPCDTHRESH_H, ®_data);//LPCD触发阈值高2位 printf("JREG_LPCDTHRESH_H = %02X\r\n",reg_data); GetReg_Ext(JREG_LPCDTXCTRL2, ®_data);//设置LPCD输出P驱动 printf("JREG_LPCDTXCTRL2 = %02X\r\n",reg_data); GetReg_Ext(JREG_LPCDTXCTRL3, ®_data);//设置LPCD输出N驱动 printf("JREG_LPCDTXCTRL3 = %02X\r\n",reg_data); GetReg_Ext(JREG_LPCDREQATIMER,®_data);//REQA检测载波时间,5ms兼容手机方案 printf("JREG_LPCDREQATIMER = %02X\r\n",reg_data); GetReg_Ext(JREG_LPCDREQAANA,®_data);//配置REQA检测命令的接收增益,接收阈值,调制宽度 printf("JREG_LPCDREQAANA = %02X\r\n",reg_data); //SetReg_Ext(JREG_LPCDDETECTMODE,LPCD_TXSCALE_4|LPCD_COMBINE_MODE);//配置REQA检测发射功率与探测输出场强的比例,LCPD探测模式设置 GetReg_Ext(JREG_LPCDDETECTMODE,®_data); printf("JREG_LPCDDETECTMODE = %02X\r\n",reg_data); return SUCCESS; } else return FAIL; } void Lpcd_Get_ADC_Value(void) { unsigned char reg,reg1; unsigned char Current1,Current2; { GetReg_Ext(JREG_LPCDICURR_HI, ®); GetReg_Ext(JREG_LPCDICURR_LO, ®1); Current1 = (reg<<6) + reg1; Current2 = ((reg<<6)>>8); printf("-> LPCD I Current is:");printf("%02X",Current2);printf("%02X",Current1);printf("\r\n"); GetReg_Ext(JREG_LPCDQCURR_HI, ®); GetReg_Ext(JREG_LPCDQCURR_LO, ®1); Current1 = (reg<<6) + reg1; Current2 = ((reg<<6)>>8); printf("-> LPCD Q Current is:");printf("%02X",Current2);printf("%02X",Current1);printf("\r\n"); GetReg_Ext(JREG_LPCDILAST_HI, ®); GetReg_Ext(JREG_LPCDILAST_LO, ®1); Current1 = (reg<<6) + reg1; Current2 = ((reg<<6)>>8); printf("-> LPCD I Last is:");printf("%02X",Current2);printf("%02X",Current1);printf("\r\n"); GetReg_Ext(JREG_LPCDQLAST_HI, ®); GetReg_Ext(JREG_LPCDQLAST_LO, ®1); Current1 = (reg<<6) + reg1; Current2 = ((reg<<6)>>8); printf("-> LPCD Q Last is:");printf("%02X",Current2);printf("%02X",Current1);printf("\r\n"); GetReg_Ext(JREG_LPCDDELTA_HI, ®); GetReg_Ext(JREG_LPCDDELTA_LO, ®1); Current1 = (reg<<6) + reg1; Current2 = ((reg<<6)>>8); printf("-> LPCD Delta is:");printf("%02X",Current2);printf("%02X",Current1);printf("\r\n"); } return; } void Lpcd_IRQ_Event(void) { unsigned char irq; Reader_Set_HPD(DISABLE); //NPD = 1,17611退出休眠模式 printf("-> LPCD Detceted!\r\n"); GetReg_Ext(JREG_LPCDIRQ, &irq);//读取LPCD中断标志 SetReg_Ext(JREG_LPCDIRQ, irq);//CLEAR LPCD IRQ printf("IRQ = %02X\r\n",irq); if(irq & 0x08) { printf("-> LPCD IRQ RFDET SET!\r\n"); } if(irq & 0x04) { printf("-> LPCD IRQ RXCHANGE SET!\r\n");//LPCD中断标志 Lpcd_Get_ADC_Value();//用于LPCD功能调试 } if(irq & 0x02) { printf("-> LPCD IRQ ATQAREC SET!\r\n"); } Reader_SoftReset(); if((irq & 0x08) ||(irq & 0x04)||(irq & 0x02)) { Lpcd_Card_Event();//卡片操作处理流程 } Lpcd_Init_Register();//LPCD初始化 Reader_Set_HPD(ENABLE);//返回LPCD模式 printf("-> LPCD ENABLE!\r\n"); return; } unsigned int Reader_ADC(void) { u8 AdcQuad_H,AdcQuad_M,AdcQuad_L; unsigned int AdcQuad; ModifyReg_Ext(JREG_LPCDTEST,BIT5,SET); DelayUs(30); GetReg_Ext(JREG_LpcdQuad_H , &AdcQuad_H); AdcQuad_H = AdcQuad_H & 0x3F; GetReg_Ext(JREG_LpcdQuad_M , &AdcQuad_M); AdcQuad_M = AdcQuad_M & 0x3F; GetReg_Ext(JREG_LpcdQuad_L , &AdcQuad_L); AdcQuad_L = AdcQuad_L & 0x3F; AdcQuad = (AdcQuad_H<<12)|(AdcQuad_M<<6)|AdcQuad_L; return AdcQuad; } unsigned char ReaderA_CW(unsigned char mode) { if(mode == ENABLE) { SetReg(JREG_TXCONTROL,0x83);//CW ON } else { SetReg(JREG_TXCONTROL,0x80);//CW OFF } DelayMs(5); return SUCCESS; } unsigned char ReaderA_Initial(void) { SetReg(JREG_MODWIDTH,0x26); //MODWIDTH = 106kbps SetReg(JREG_TXAUTO,0x40);//Force 100ASK = 1 SetReg(JREG_GSN,CWN<<4);//Config GSN; Config ModGSN SetReg(JREG_CWGSP,CWP);//Config GSP SetReg(JREG_CONTROL,0x10);//Initiator = 1 SetReg(JREG_RFCFG,RX_GAIN<<4);//Config RxGain SetReg(JREG_RXTRESHOLD,(RX_MINLEVEL<<4)|RX_COLLLEVEL);//Config MinLevel; Config CollLevel return SUCCESS; } unsigned char ReaderA_Request(unsigned char *atqa) { unsigned char reg_data; SetReg(JREG_TXMODE,0);//Disable TxCRC SetReg(JREG_RXMODE,0);//Disable RxCRC SetReg(JREG_COMMAND,0x00);//command = Idel SetReg(JREG_FIFOLEVEL,0x80);//Clear FIFO SetReg(JREG_FIFODATA,0x26); SetReg(JREG_COMMAND,0x0C);//command = Transceive SetReg(JREG_BITFRAMING,0x87);//Start Send DelayUs(500);// GetReg(JREG_FIFOLEVEL,®_data); if(reg_data == 2) { GetReg(JREG_FIFODATA,&atqa[0]); GetReg(JREG_FIFODATA,&atqa[1]); //if((atqa[0]==0x44)&&(atqa[1]==0x00))//可以增加卡片类型判断 { return SUCCESS; } } return FAIL; } unsigned char ReaderA_Anticol(unsigned char cmd,unsigned char *uid) { unsigned char reg_data; SetReg(JREG_TXMODE,0x00);//Disable TxCRC SetReg(JREG_RXMODE,0x00);//Disable RxCRC SetReg(JREG_COMMAND,0x00);//command = Idel SetReg(JREG_FIFOLEVEL,0x80);//Clear FIFO SetReg(JREG_FIFODATA,cmd); SetReg(JREG_FIFODATA,0x20); SetReg(JREG_COMMAND,0x0C);//command = Transceive SetReg(JREG_BITFRAMING,0x80);//Start Send DelayUs(1000);//实测时间us GetReg(JREG_FIFOLEVEL,®_data); if(reg_data != 5) { //printf("ANTICOLL ERROR\r\n"); return FAIL; } GetReg(JREG_FIFODATA,&uid[0]); GetReg(JREG_FIFODATA,&uid[1]); GetReg(JREG_FIFODATA,&uid[2]); GetReg(JREG_FIFODATA,&uid[3]); GetReg(JREG_FIFODATA,&uid[4]); if((uid[0]^uid[1]^uid[2]^uid[3]) != uid[4]) { return FAIL; } return SUCCESS; } unsigned char ReaderA_Select(unsigned char cmd,unsigned char *uid,unsigned char *sak) { unsigned char reg_data; SetReg(JREG_TXMODE,0x80);//Enable TxCRC SetReg(JREG_RXMODE,0x80);//Enable RxCRC SetReg(JREG_COMMAND,0x00);//command = Idel SetReg(JREG_FIFOLEVEL,0x80);//Clear FIFO SetReg(JREG_FIFODATA,cmd); SetReg(JREG_FIFODATA,0x70); SetReg(JREG_FIFODATA,uid[0]); SetReg(JREG_FIFODATA,uid[1]); SetReg(JREG_FIFODATA,uid[2]); SetReg(JREG_FIFODATA,uid[3]); SetReg(JREG_FIFODATA,uid[4]); SetReg(JREG_COMMAND,0x0C);//command = Transceive SetReg(JREG_BITFRAMING,0x80);//Start Send DelayUs(1100);// GetReg(JREG_FIFOLEVEL,®_data); if(reg_data != 1) { //printf("SELECT ERROR\r\n"); return FAIL; } GetReg(JREG_ERROR,®_data);//判断错误寄存器 if(reg_data != 0) { return FAIL; } GetReg(JREG_FIFODATA,&*sak); return SUCCESS; } unsigned char Lpcd_Card_Event(void) { unsigned char result; ReaderA_Initial(); //TYPE A 初始化 ReaderA_CW(ENABLE); //打开载波输出 UID_SIZE = 8; memset(UID,0,UID_SIZE);//UID初始化为0 result = ReaderA_Request(ATQA); if(result != SUCCESS) { ReaderA_CW(DISABLE); //printf("REQA_ERROR\r\n"); return FAIL; } //printf( "ATQA%02X = %02X%02X\r\n",READER_NUM,ATQA[num][0], ATQA[num][1]); //打印ATQA数据 result = ReaderA_Anticol(0x93,UID); if(result != SUCCESS) { memset(UID,0,UID_SIZE);//清除错误的UID ReaderA_CW(DISABLE); //printf("ReaderA_Anticol_ERROR\r\n"); return FAIL; } result = ReaderA_Select(0x93,UID,SAK); if(result != SUCCESS) { memset(UID,0,UID_SIZE);//清除错误的UID ReaderA_CW(DISABLE); //printf("ReaderA_Select_ERROR\r\n"); return FAIL; } //printf( "SAK%02X = %02X\r\n",READER_NUM,SAK[num][0]);//打印SAK数据 if(UID[0]!= 0x88) { UID_SIZE = 4; printf("-> ATQA = %02X%02X\r\n",ATQA[0],ATQA[1]); printf("-> UID = %02X%02X%02X%02X\r\n",UID[0],UID[1],UID[2],UID[3]); printf("-> SAK = %02X\r\n",SAK[0]); //此处添加用户卡片操作函数 //MIFARE_EVENT(); //用户卡片操作函数结束 ReaderA_CW(DISABLE); //关闭载波输出 return result; } else { UID_SIZE = 8; } result = ReaderA_Anticol(0x95,UID+4); if(result != SUCCESS) { memset(UID,0,UID_SIZE);//清除错误的UID ReaderA_CW(DISABLE); //printf("ReaderA_Anticol_ERROR\r\n"); return FAIL; } result = ReaderA_Select(0x95,UID+4,SAK); if(result != SUCCESS) { memset(UID,0,UID_SIZE);//清除错误的UID ReaderA_CW(DISABLE); //printf("ReaderA_Select_ERROR\r\n"); return FAIL; } printf("-> ATQA = %02X%02X\r\n",ATQA[0],ATQA[1]); printf("-> UID = %02X%02X%02X%02X%02X%02X%02X%02X\r\n",UID[0],UID[1],UID[2],UID[3],UID[4],UID[5],UID[6],UID[7]); printf("-> SAK = %02X\r\n",SAK[0]); //此处添加用户卡片操作函数 //NTAG_EVENT(); //用户卡片操作函数结束 return result; } unsigned char FastRead_Page(unsigned char page_num1,unsigned char page_num2,unsigned char *page_data,unsigned char encrypt) { unsigned char reg_data,i,send_data[3],length; SetReg(0x12,0x80);//Enable TxCRC SetReg(0x13,0x80);//Enable RxCRC SetReg(0x01,0x00);//command = Idel SetReg(0x0A,0x80);//Clear FIFO send_data[0] = 0x3A; send_data[1] = page_num1; send_data[2] = page_num2; if(encrypt == ENABLE ) { PRINT_Calc_sendData(send_data,3); } SetReg(0x09,send_data[0]); SetReg(0x09,send_data[1]); SetReg(0x09,send_data[2]); SetReg(0x01,0x0C);//command = Transceive SetReg(0x0D,0x80);//Start Send DelayUs(3000);//实测时间us GetReg(0x0A,®_data); //printf("fastreadpage rece_length = %X \r\n",reg_data); length = (page_num2-page_num1+1)*4; if(reg_data == length) { for(i=0;i>(i*8); } //printf("PICC_PCD_random = %02X%02X%02X%02X%02X%02X\r\n",PICC_PCD_random[0],PICC_PCD_random[1],PICC_PCD_random[2],PICC_PCD_random[3],PICC_PCD_random[4],PICC_PCD_random[5]); Print_AUTH(key,PICC_PCD_random,rece_buff);//print认证 for(i=0;i<6;i++) { Token1[i] = rece_buff[5-i];//倒序 } //authstat = AUTH_STAT_1; result = TPDU(6,Token1,6,rece_buff,6000); if(result != SUCCESS) { printf("TPDU2 ERROR\r\n"); return result; } for(i=0;i<6;i++) { Token2[i] = rece_buff[5-i];//倒序 } //printf("Token2 = %2X%02X%02X%02X%02X%02X\r\n",Token2[0],Token2[1],Token2[2],Token2[3],Token2[4],Token2[5]); Print_AUTH(key,Token2,rece_buff);//将Token2 print解密,前四个字节和PCD_random对比,对比成功说明认证成功 //printf("rece_buff = %02X%02X%02X%02X%02X%02X\r\n",rece_buff[0],rece_buff[1],rece_buff[2],rece_buff[3],rece_buff[4],rece_buff[5]); for(i = 0;i < 4;i++) { PICC_PCD_random[2+i] = random_data>>(i*8); } //printf("PICC_PCD_random = %02X%02X%02X%02X%02X%02X\r\n",PICC_PCD_random[0],PICC_PCD_random[1],PICC_PCD_random[2],PICC_PCD_random[3],PICC_PCD_random[4],PICC_PCD_random[5]); if(memcmp(rece_buff,PICC_PCD_random+2,4)) { return FAIL; } else { lsfr_init(rece_buff);//初始化密码流为之后的读写认证准备 return SUCCESS; } }