Forum / MIFARE and NFC Reader IC`s / Can´t get Anticollision loop with two PICCs.
Tagged: Anticollision
-
Hello,
I´m working with RC522 and I´m dealing with the anticolision loop when two tags are shown in the antenna. The two tags I am working with have the following UIDs:
PICC #1: 86 A0 83 EE
PICC #2: 16 9A 0A 3B
When PCD sends SEL + NVB (0x93 + 0x20), both PICC answer and the information I get from the registers is the following:
ComIrqReg: 0x66.
Bit TxIRq = 1.
Bit RxIRq = 1. (The end of a valid stream detected)
Bit ErrIRq = 1. (Error bit in ErrorReg is set)
ErrorReg: 0x08.
Bit CollErr = 1. (A collision detected)
CollErr: 0x05.
Bit CollPosNotValid = 0
Bit CollPos[4..0] = 05. (Collision in the fifth bit.)
Let´s confirm the collision is in the fifth bit:
PICC #1 UID0 = 0x86 = 1000 0110
PICC #2 UID0 = 0x16 = 0001 0110
However my doubts are about the information PCD has to send back to the PICC and the value of BitFrammingReg Register:
BitFrammingReg=0x55 and SEL (0x93) + NVD (0x25)+ 10110 ?????
Or BitFrammingReg=0x55 and SEL (0x93) + NVD (0x25)+ 01101 ?????
I tried different options but I'm not able to succeed. Please find attached the code file in case somebody could have a look and give me a clue.
Any help will be apreciated. Thank you.
`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.
WriteRegister(FIFODataReg,0x25); // NVB to FIFO. provi
WriteRegister(FIFODataReg,0x16); // provi
//for(ucRepeat = 0; ucRepeat < ucNumBytesBuf; ucRepeat ++)
// WriteRegister(FIFODataReg, BufFIFO[ucRepeat]<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);
}
`
+ 0 | - 0
Hi Aitor,
What is missing is the FIFO! Even when a (collision) error was detected, it exists received bytes in the FIFO (in this case only one). The fifth bit has the collision, but the valid four from FIFO must be fetched. These valid four bits plus the fifth bit (either 1 or 0) must be sent back with 92 25.
The TapLinx team
+ 0 | - 0
Thank you for your answer,
I checked the firmware and I found a bug. It is fine now. However, I see that some pair of cards work better than others.
I have a pair of tags where the collision is detected properly (CollErr flag from ErrorREG set) but then CollPoss bits (in CollReg) show the erroneous position of the collision. As I said, sometimes works fine and some others not. I am quite confused. Does is something to do with the MinLevel and CollLevel in RxThresholdReg? I don´t know how they shoul be configured.
Could it be due to the gain? I configured to the the maximum.
Thanks again for your help.
BR.
Aitor.
+ 0 | - 0
Hi Aitor,
Two annotations:
“Collision detected” is a necessary but not a sufficient condition for a collision. This means sometimes a collision is detected properly, but sometimes not. It is not the goal for an anti-collision to detect a collision, but rather to select a card in the field properly. If the card is selected by the reader, it can be deselected and the other card in the field can be selected.
The anti-collision needs the adherence of an exact bit pattern. If for instance the quality of the reader is very high and the slopes of the sending pulse is diffuse, then the answer varies (jitter!) in particular if different card types are used. This can make the collision appear on wrong positions.
The TapLinx team
+ 1 | - 0
Thank you for your reply.
BR
+ 0 | - 0
Oh! This is so nice to know.
+ 0 | - 0
+ 0 | - 0
+ 0 | - 0
-
AuthorPosts
Viewing 8 posts - 1 through 8 (of 8 total)
You must be logged in to reply to this topic.