#include "mifareRC522_V4.h" #include "Anticollision.h" #include "iom328p.h" #include "spi.h" #define WriteReg(dir) (dir<<1) #define ReadReg(dir) (dir<<1)|0x80 uchar BufFIFO[64]; unsigned int uiAtqa; extern uint uiMinna; extern uchar ucHigh, ucLow, ucErr, ucRegistro_ErrorReg, ucRegistro_CollReg, ucRegistro_ComIrgReg, ucCollPos, ucArrUID[5], ucTiempoOUT; // PROVIPROVI unsigned char ucSak; ////////////////////////////////////////////////////////////////////// // S E T A B I T M A S K /////////////////////////////////////////////////////////////////////// void SetBitMask(unsigned char reg,unsigned char mask) // { char tmp = 0x0; tmp = ReadRegister(reg); WriteRegister(reg,tmp | mask); // set bit mask } ////////////////////////////////////////////////////////////////////// // C L E A R A B I T M A S K ////////////////////////////////////////////////////////////////////// void ClearBitMask(unsigned char reg,unsigned char mask) // { char tmp = 0x0; tmp = ReadRegister(reg); WriteRegister(reg,tmp & ~mask); // clear bit mask } void WriteRegister (uchar ucDir, uchar ucDato) { clr_bit(PORTB,p_MifareSel); PutSPI(WriteReg(ucDir)); PutSPI(ucDato); set_bit (PORTB, p_MifareSel); } uchar ReadRegister (uchar ucDir) { uchar ucResult; clr_bit(PORTB,p_MifareSel); PutSPI(ReadReg(ucDir)); ucResult = GetSPI(); set_bit (PORTB, p_MifareSel); return(ucResult); } void FlushFIFO(void) { SetBitMask(FIFOLevelReg,0x80); } uchar fPCD_TRANSCEIVE (uchar ucTimeOutLocal) { //Ejecuto el comando de lectura. WriteRegister(CommandReg,PCD_TRANSCEIVE); SetBitMask(BitFramingReg,0x80); //Espero a que se complete el comando transceive. while(((ReadRegister(ComIrgReg) & 0x20)==0)&&(ucTimeOutLocal>0)) { RetardoMseg(1); ucTimeOutLocal--; } WriteRegister(CommandReg,PCD_IDLE); // terminate probably running command return(ucTimeOutLocal); } void MfRC522Reset (uchar ucGain) { while((ReadRegister(CommandReg)&0x0F)!= 0) { ; } WriteRegister(CommandReg,0x20); WriteRegister(CollReg, 0x80);// ValuesAfterColl=1 => Bits received after collision are cleared. WriteRegister(ModeReg, 0x3D); // CRCPReset 0x6363 WriteRegister(TxModeReg,0x00); // TxCRCEn=0, TxSpeed=106kbit/seg, InvMod=0 WriteRegister(RxModeReg,0x00); //RxCRCEn=0, RxSpeed=106kbit/s, RxNoErr=RxMultiple=0 WriteRegister(TxControlReg,0x83); //Tx2Inverted, Antena de momento activada. // TX2RfEn y TX1RfEn = 1 WriteRegister(TxASKReg,0x40); //Force100ASK=ON WriteRegister(TxSelReg,0x10); //DriverSel=Internal Coder. // NUEVO NO LO TIENE //Registro RxSelReg, de momento no tocamos. RxWait en dudas. En el lector viejo venía a 6 y ahora //viene a 4. Hay que probarlo. WriteRegister(RxSelReg,0x84); // NUEVO NO LO TIENE //WriteRegister(RxThresholdReg,0x84); //De momento mantenemos a espera de las pruebas reales. //WriteRegister(RxThresholdReg,0x55); //De momento mantenemos a espera de las pruebas reales. // ALGUNOS. WriteRegister(RxThresholdReg,0x74); //De momento mantenemos a espera de las pruebas reales. // OK //WriteRegister(RxThresholdReg,0x75); //De momento mantenemos a espera de las pruebas reales. // PEGATINAS MIKEL SI. //WriteRegister(RxThresholdReg,0x77); //De momento mantenemos a espera de las pruebas reales.################## WriteRegister(DemodReg,0x4D); //De momento se mantiene como viene. Dudas a probar. //Las dos Taus antes las teníamos a 0????? //Dudas con Q or I Clock. Antes usabamos Q Clock. Ahora se uasa //el más fuerte. Hay que probar. //De momemto MfTxReg no tocamos. TxWait??? WriteRegister(MfRxReg,0x00); //Avtivamos parity para las comunicaciones. // NUEVO NO LO TIENE. WriteRegister(ModWidthReg,0x26); //Mantenemos el valor por defecto. Antes usabamos 13?? //WriteRegister(RfCfgReg,ucGain); //De momento empezamos con la ganacia máxima de 48db. ClearBitMask(RfCfgReg, (0x07<<4)); // clear needed to allow 000 pattern SetBitMask(RfCfgReg, (0x07<<4)); // only set RxGain[2:0] bits //WriteRegister(RfCfgReg,0x78); //De momento empezamos con la ganacia máxima de 48db. //WriteRegister(RfCfgReg,0x60); //De momento empezamos con la ganacia máxima de 48db. //Hay que probar como se comporta el circuito con las distintas //gananacias para ajustarla en EscribeMifare. //WriteRegister(GsNReg,0xFF); //Se cambia a 3F (maximo). Para ajustar distancias y consumos. WriteRegister(GsNReg,0x88); //Se cambia a 3F (maximo). Para ajustar distancias y consumos. //WriteRegister(CWGsPReg,0x3F); //Se cambia a 3F (maximo). Para ajustar distancias y consumos. WriteRegister(CWGsPReg,0x20); //Se cambia a 3F (maximo). Para ajustar distancias y consumos. //Registro 29, ModGsPReg no se tiene en cuenta cuando el bit Force100ASK esta a 1. //Desde el 2A hasta el 2F registros del timer. No se usan. //Desde el 30 hasta el 3F son registros de Test. //WriteRegister(CommandReg,0x30); // Receiver OFF, PowerDown a ON y comando 0000 Idle MODI V02.2-27 } unsigned char MfRC522PICCRequest (unsigned char ucReqCode) { uchar ucTimeOut=3; uiAtqa = 0; WriteRegister(TxModeReg,0x00); // TxCRCEn=0, TxSpeed=106kbit/seg, InvMod=0 WriteRegister(RxModeReg,0x00); // RxCRCEn=0, RxSpeed=106kbit/s, RxNoErr=RxMultiple=0 WriteRegister(CommandReg,PCD_IDLE); // Terminate probably running command WriteRegister(MfRxReg,0x10); // Parity disabled. ClearBitMask(Status2Reg,0x08); // Disable crypto 1 unit ClearBitMask(CollReg,0x80); // ValuesAfterColl = 0 Clear all received bits. WriteRegister(BitFramingReg,0x07); // For REQA and WUPA we need the short frame format - transmit only 7 bits of the last (and only) byte. TxLastBits = BitFramingReg[2..0] // RxAlign = 0, txLastBits = 7. WriteRegister(ComIrgReg,0x7f); WriteRegister(DivIrqReg,0x7f); SetBitMask(FIFOLevelReg,0x80); // Flush FIFO. //--------------------------------------------------------------------------- WriteRegister(FIFODataReg,ucReqCode); // REQUEST code (0x26) to FIFO. WriteRegister(CommandReg,PCD_TRANSCEIVE); // TRANSCEIVE. SetBitMask(BitFramingReg,0x80); // StartSend bit enabled: this bit starts the transmission. //--------------------------------------------------------------------------- ucRegistro_ComIrgReg = 0; while(((ucRegistro_ComIrgReg & 0x20)==0)&&(ucTimeOut>0)) // Wait to RxIRq=1: end of a valid data stream detected. { ucRegistro_ComIrgReg = ReadRegister(ComIrgReg); RetardoMseg(1); ucTimeOut--; } if (ucTimeOut>0) { BufFIFO[0] = ReadRegister(FIFODataReg); // ATQA LOW. BufFIFO[1] = ReadRegister(FIFODataReg); // ATQA HIGH. } ucRegistro_ErrorReg = ReadRegister(ErrorReg); ucRegistro_CollReg = ReadRegister(CollReg); uiAtqa = ((uint)BufFIFO[1] << 8) | (uint)BufFIFO[0]; if(uiAtqa == 0x0000) ucTimeOut=0; return (ucTimeOut); } unsigned char MfRC522PICCAnticoll (unsigned char ucNivelLocal) { uchar ucTimeOut=3, ucRepeat, ucTotalBitsTX=0, ucNVB=0, ucRxAlign=0, ucTxLastBits=0, ucNumBytesBuf=0; WriteRegister(TxModeReg,0x00); // TxCRCEn=0, TxSpeed=106kbit/seg, InvMod=0 WriteRegister(RxModeReg,0x00); // RxCRCEn=0, RxSpeed=106kbit/s, RxNoErr=RxMultiple=0 WriteRegister(CommandReg,PCD_IDLE); // Terminate probably running command WriteRegister(MfRxReg,0x00); // Parity enabled. ClearBitMask(Status2Reg,0x08); // Disable crypto 1 unit ClearBitMask(CollReg,0x80); // ValuesAfterColl=1. Clean all bits after a collision. WriteRegister(BitFramingReg,0x00); // set TxLastBits to 8 WriteRegister(ComIrgReg,0x7f); WriteRegister(DivIrqReg,0x7f); SetBitMask(FIFOLevelReg,0x80); // Flush FIFO. //--------------------------------------------------------------------------- WriteRegister(FIFODataReg,0x93); // ANTICOLLISION code (0x93) to FIFO. WriteRegister(FIFODataReg,0x20); // NVB=0x20 to FIFO. ucRegistro_ComIrgReg = 0; WriteRegister(CommandReg,PCD_TRANSCEIVE); // TRANSCEIVE. SetBitMask(BitFramingReg,0x80); // StartSend bit enabled: this bit starts the transmission. //--------------------------------------------------------------------------- while(((ucRegistro_ComIrgReg & 0x20)==0)&&(ucTimeOut>0)) // Wait to RxIRq=1: end of a valid data stream detected. { ucRegistro_ComIrgReg = ReadRegister(ComIrgReg); RetardoMseg(1); ucTimeOut--; } ucRegistro_ErrorReg = ReadRegister(ErrorReg); ucRegistro_CollReg = ReadRegister(CollReg); BufFIFO[0] = ReadRegister(FIFODataReg); //UID0 BufFIFO[1] = ReadRegister(FIFODataReg); //UID1 BufFIFO[2] = ReadRegister(FIFODataReg); //UID2 BufFIFO[3] = ReadRegister(FIFODataReg); //UID3 BufFIFO[4] = ReadRegister(FIFODataReg); //BCC. //--------------------------------------------------------------------------- // Write in EEPROM to check the values. Write_EEPROM(0x10+uiMinna,ucRegistro_ComIrgReg); // Result: 0x66 RxIRq and ErrIRq. uiMinna ++; Write_EEPROM(0x10+uiMinna,ucTimeOut); // Result: 0x01 Data received before timeout. uiMinna ++; Write_EEPROM(0x10+uiMinna,ucRegistro_ErrorReg); // Result: 0x08 Collision detected. uiMinna ++; Write_EEPROM(0x10+uiMinna,ucRegistro_CollReg); // Result: 0x05 Position of the collision. uiMinna ++; Write_EEPROM(0x10+uiMinna,BufFIFO[0]); // Result: 0x16 uiMinna ++; Write_EEPROM(0x10+uiMinna,BufFIFO[1]); // Result: --- uiMinna ++; Write_EEPROM(0x10+uiMinna,BufFIFO[2]); // Result: --- uiMinna ++; Write_EEPROM(0x10+uiMinna,BufFIFO[3]); // Result: --- uiMinna ++; //--------------------------------------------------------------------------- if ((BufFIFO[0]^BufFIFO[1]^BufFIFO[2]^BufFIFO[3])!= BufFIFO[4] ) // Check BCC. ucTimeOut=0; if(!(ucRegistro_ErrorReg & maskCOLL_ERR)) // If bit CollErr = 0, there is no collision. return (TRUE); else { // If bit CollErr = 1, there is a collision. if(ucRegistro_CollReg & maskCOLL_POS_NOT_VALID) { return (FALSE); } else { ucCollPos = ucRegistro_CollReg & 0x1F; // Keep the 5 lowest bits. CollPos[4..0] show the position of the collision. if (ucCollPos == 0) ucCollPos = 32; // Settings for the next transmission. WriteRegister(CommandReg,PCD_IDLE); // Terminate probably running command //WriteRegister(MfRxReg,0x00); // Parity enabled. //ClearBitMask(Status2Reg,0x08); // Disable crypto 1 unit ClearBitMask(CollReg,0x80); // ValuesAfterColl=1 => LIMPIAMOS TODOS LOS BITS RECIBIDOS DESPUES DE UNA COLLISION. WriteRegister(BitFramingReg,0x00); WriteRegister(ComIrgReg,0x7f); WriteRegister(DivIrqReg,0x7f); SetBitMask(FIFOLevelReg,0x80); // Flush FIFO. // New NVB value. // The upper 4 bits are called “Byte count” and specify the integer part of the number of all valid data bits transmitted // by the PCD (including SEL and NVB) divided by 8. Consequently, the minimum value of “Byte count” is 2 and the maximum value is 7. // The lower 4 bits are called “bit count” and specify the number of all valid data bits transmitted by the PCD (including SEL // and NVB) modulo 8. ucTotalBitsTX = 16 + ucCollPos; // We must add 16 bits (SEL+NVB) to the number of 'common' bits of the collision. ucNVB = ((ucTotalBitsTX/8) << 4) | (ucTotalBitsTX%8); // 'BitFramingReg' setting. ucTxLastBits = ucTotalBitsTX % 8; ucRxAlign = ucTxLastBits; WriteRegister(BitFramingReg, (ucRxAlign << 4) + ucTxLastBits); // ??????????????????????????????? if((ucTotalBitsTX%8) == 0) // Number of bytes to be sent after SEL + NVB. ucNumBytesBuf = (ucTotalBitsTX/8)-2; else ucNumBytesBuf = ((ucTotalBitsTX/8)-2)+1; // A byte is added if there is any 'release' bit. //--------------------------------------------------------------------------- WriteRegister(FIFODataReg,0x93); // ANTICOLLISION code (0x93) to FIFO. WriteRegister(FIFODataReg,ucNVB); // NVB to FIFO. for(ucRepeat = 0; ucRepeat < ucNumBytesBuf; ucRepeat ++) WriteRegister(FIFODataReg, BufFIFO[ucRepeat]<<(8-ucTxLastBits)); // 'Common' bits to FIFO. ???????????????????????????????? ucRegistro_ComIrgReg = 0; WriteRegister(CommandReg,PCD_TRANSCEIVE); // TRANSCEIVE. SetBitMask(BitFramingReg,0x80); // StartSend bit enabled: this bit starts the transmission. //--------------------------------------------------------------------------- while(((ucRegistro_ComIrgReg & 0x20)==0)&&(ucTimeOut>0)) // Wait to RxIRq=1: end of a valid data stream detected. { ucRegistro_ComIrgReg = ReadRegister(ComIrgReg); RetardoMseg(1); ucTimeOut--; } ucRegistro_ErrorReg = ReadRegister(ErrorReg); ucRegistro_CollReg = ReadRegister(CollReg); BufFIFO[0] = ReadRegister(FIFODataReg); //UID0 BufFIFO[1] = ReadRegister(FIFODataReg); //UID1 BufFIFO[2] = ReadRegister(FIFODataReg); //UID2 BufFIFO[3] = ReadRegister(FIFODataReg); //UID3 BufFIFO[4] = ReadRegister(FIFODataReg); //CHK //--------------------------------------------------------------------------- // Write in EEPROM to check. Write_EEPROM(0x10+uiMinna,ucRegistro_ComIrgReg); // Result: 0x00 Not valid stream. uiMinna ++; Write_EEPROM(0x10+uiMinna,ucTimeOut); // Result: 0x00 uiMinna ++; Write_EEPROM(0x10+uiMinna,ucRegistro_ErrorReg); // Result: 0x00 uiMinna ++; Write_EEPROM(0x10+uiMinna,ucRegistro_CollReg); // Result: 0x25 uiMinna ++; Write_EEPROM(0x10+uiMinna,BufFIFO[0]); // Result: --- uiMinna ++; Write_EEPROM(0x10+uiMinna,BufFIFO[1]); // Result: --- uiMinna ++; Write_EEPROM(0x10+uiMinna,BufFIFO[2]); // Result: --- uiMinna ++; Write_EEPROM(0x10+uiMinna,BufFIFO[3]); // Result: --- uiMinna ++; //--------------------------------------------------------------------------- // Pending... } } return(ucTimeOut); } unsigned char MfRC522PICCSel (uchar ucNivel, uchar uid0, uchar uid1, uchar uid2, uchar uid3) { uchar ucTimeOut=3; WriteRegister(CommandReg,PCD_IDLE); // Terminate probably running command. Stop any active command. WriteRegister(TxModeReg,0x00); // TxCRCEn=0, TxSpeed=106kbit/seg, InvMod=0 WriteRegister(RxModeReg,0x00); // RxCRCEn=0, RxSpeed=106kbit/s, RxNoErr=RxMultiple=0 // WriteRegister(TxModeReg,0x80); // TxCRCEn=1, TxSpeed=106kbit/seg, InvMod=0 // OJO, NOSOTROS HASTA AHORA ACTIVABAMOS LA GENERACIÓN DE CRC. !!!!!!!! // WriteRegister(RxModeReg,0x80); // RxCRCEn=1, RxSpeed=106kbit/s, RxNoErr=RxMultiple=0 WriteRegister(MfRxReg,0x00); // Parity enabled. // OJO, DIFERENTE RESPECTO A LA ANTICOLLISION !!!!!!!!!!!!!!!!!!!!!!!!!!! ClearBitMask(Status2Reg,0x08); // Disable crypto 1 unit ClearBitMask(CollReg,0x80); // ValuesAfterColl = 0 Clear all received bits. WriteRegister(BitFramingReg,0x00); // TxLastBits = 000. All bits will be transmitted. // OJO, DIFERENTE RESPECTO A LA ANTICOLLISION !!!!!!!!!!!!!!!!!!!!!!!!! WriteRegister(ComIrgReg,0x7f); WriteRegister(DivIrqReg,0x7f); SetBitMask(FIFOLevelReg,0x80); // Flush FIFO. if(ucNivel == NIVEL_1)// MODI ULTRA WriteRegister(FIFODataReg,0x93); //Comando select (1º nivel) else if(ucNivel == NIVEL_2) WriteRegister(FIFODataReg,0x95); //Comando select (2º nivel) else return(0); WriteRegister(FIFODataReg,0x70); //NVB = 0x70, vamos a enviar 56bits. Todo el UID recibido WriteRegister(FIFODataReg,uid0); //uid0 WriteRegister(FIFODataReg,uid1); //uid1 WriteRegister(FIFODataReg,uid2); //uid2 WriteRegister(FIFODataReg,uid3); //uid3 WriteRegister(FIFODataReg,uid0^uid1^uid2^uid3); //bcc ucTimeOut = fPCD_TRANSCEIVE(ucTimeOut); // LA COMPROBACIÓN DEL BIT RxIRq LO HACEMOS JUSTO DEPUES DEL TRANSCEIVE. ucRegistro_ComIrgReg = 0; while(((ucRegistro_ComIrgReg & 0x20)==0)&&(ucTimeOut>0)) // Wait to RxIRq=1: end of a valid data stream detected. { ucRegistro_ComIrgReg = ReadRegister(ComIrgReg); RetardoMseg(1); ucTimeOut--; } ucSak = 0; // MODI F.V01.0-2a ucSak = ReadRegister(FIFODataReg); /* // MODI F.V01.0-2a El valor SAK no lo comprobamos como byte entero sino bit a bit. //Se comprueba el SAK. Tiene que ser un SAK conocido. if((ucSak != SAK_MIF_1K) && (ucSak != SAK_MIF_4K) && (ucSak != SAK_INFINEON_1K) && (ucSak != SAK_MIF_UL_NIVEL1)&& (ucSak != SAK_MIF_UL_NIVEL2)&& (ucSak != SAK_MIF_MINI))//MODI ULTRA ucTimeOut=0; */ return(ucTimeOut); }