📄 prd_iso15693_anticollision.c
字号:
//=============================================================================
// Copyright (C) INSIDE Contactless 1998-2005
//
// INSIDE Contactless reserves the right to make changes, without notice,
// to any product (including application note) herein to improve
// reliability, functionality, or design. INSIDE Contactless advises its
// customers to obtain the latest version of device data sheets to verify,
// before placing orders, that the information being relied upon by the
// customer is current.
//
// INSIDE Contactless makes no warranty that the use will not infringe any
// third party patent, copyright or trademark.
//
// Information furnished by INSIDE Contactless is believed to be accurate
// and reliable. However, INSIDE Contactless does not assume any liability
// resulting from the application or use of any product described within.
//
// All rights are reserved. Reproduction in whole or in part is prohibited
// without the written consent of the copyright owner.
//
// Bat 11a,
// Parc Club du Golf,
// Z.A.C. du Pichaury Tel : +33 (0)4.42.39.33.00
// 13856 Aix-en-Provence Cedex 3 Fax : +33 (0)4.42.39.63.19
// FRANCE Email : info@insidefr.com
//
//-----------------------------------------------------------------------------
// Project Code : PICOREAD RF ISO15693-3 READER
// Project Name : APPLICATION NOTE
// Module Name : PRD_ISO15693_ANTICOLLISION.H
// Platform dev : Keil 礦ision 3 (IDE ) + Keil ARM Compiler
// Target : GENERIC
// Language : C ANSI
// Revision : 1.1
// Description :
//=============================================================================
// Defines standard
#include <string.h> // Standard C Libray file containing basic functions to use serial host
// Defines for common C writting
#include "Defines_C.h" // TRUE, FALSE, etc
// Defines for PicoRead
#include "PRD_PicoReadRF_Pages_Parameters.h" // Definition of PicoRead chip registers
#include "PRD_Config.h" // Reader Configuration functions
#include "PRD_RF_Comm.h"
#include "PRD_BufferExchange.h"
// Defines for the target
#include "Target.H" // Definition of processor registers & Low level functions to be modified according to the target, and the user needs
// ISO 15693 Commands
#include "PRD_ISO15693_Commands.h"
#include "PRD_COMMON_Anticollision_Parameters.h" //Common Anticollision parameters defines
#include "PRD_ISO15693_Anticollision_Parameters.h" //Anticollision parameters defines for ISO15693
#include "PRD_ISO15693_Anticollision_Default_Parameters.h" //Default Anticollsion parameters for ISO15693
#include "PRD_ISO15693_Anticollision.h" // Anticollision functions for ISO15693
//#ifdef FULL
//-----------------------------------------------------------------------------
// Function name : BYTE b_fn15693_Anticol(BYTE* p_abUID, BYTE* p_bUIDLength)
//-----------------------------------------------------------------------------
// Description : Extract one card from x card and return the UID of the selected
// card using the ISO15693 protocol.
//
// IN : p_pStructReader : Pointer to the used StructReader structure.
//
// OUT : p_abUID : UID received
// p_bUIDLength : UID size (8)
//
// RETURN : true 1 if a card is selected.
// false 0 no card selected.
//
// Notes : This function makes several attemps before returning an error.
//-----------------------------------------------------------------------------
unsigned char b_fnISO15693_Anticol(unsigned char* p_abUID, unsigned char* p_bUIDLength,StructReader* p_pStructReader)
{
unsigned short l_wRFPicoReadByteCounter;
unsigned char l_bRFPicoReadBitCounter;
unsigned char l_bPicoReadStatus;
unsigned char l_bRFReceiveEOF;
unsigned char l_abBuffer[256];
unsigned char l_indSlot, l_iMaxSlot, l_iMaskLength;
unsigned char l_abMask[8];
unsigned char l_bInvFlag;
unsigned char l_bStatus;
unsigned char l_bDelay;
unsigned char l_bRetry;
unsigned char l_bBitToReceive=0;
l_bRetry=(p_pStructReader->s_bRAnticolOpt1 & 0x03);
lbl_Loop:
p_pStructReader->s_bRTimeoutUsed=TO_604US;
l_bInvFlag=((p_pStructReader->s_bRAnticolOpt0 & ISO150_1SLOT)>>0x02) | 0x10; // AFI & Nb Slot flags
// TEST IF ONLY ONE CHIP IN FIELD
l_abBuffer[0] = _ISO15_INVFLAG|0x30;
l_abBuffer[1] = _ISO15_INVENTORY;
l_abBuffer[2] = p_pStructReader->s_bRAnticolOpt2;
l_abBuffer[3] = 0x00;
v_fnSendBuffer(_SENDCRC,4,0,&l_abBuffer[0],p_pStructReader);
if(b_fnReceiveBuffer(_CHECKCRC,&l_abBuffer[0],p_pStructReader,&l_wRFPicoReadByteCounter,&l_bRFPicoReadBitCounter,&l_bPicoReadStatus,&l_bRFReceiveEOF,&l_bBitToReceive)==ERR_NO_ERROR)
{
// PUT UID ON BUFFER
memcpy(&p_abUID[0],&l_abBuffer[2],8);
*p_bUIDLength=8;
goto lbl_Stayquiet;
}
// GET SLOT NUMBER
if (l_bInvFlag & 0x20) l_iMaxSlot = 0;
else l_iMaxSlot = 15;
// INVENTORY COMMAND (NO MASK) - COMMAND GENERATION
l_abBuffer[0] = _ISO15_INVFLAG + l_bInvFlag;
l_abBuffer[1] = _ISO15_INVENTORY;
l_abBuffer[2] = p_pStructReader->s_bRAnticolOpt2;
l_abBuffer[3] = 0x00;
// INVENTORY COMMAND (NO MASK) - COMMAND EXECUTION
for(l_bDelay=15;l_bDelay>0;l_bDelay--) delay_us(200); // delay 3 ms
v_fnSendBuffer(_SENDCRC,4,0,&l_abBuffer[0],p_pStructReader);
l_bStatus=b_fnReceiveBuffer(_CHECKCRC,&l_abBuffer[0],p_pStructReader,&l_wRFPicoReadByteCounter,&l_bRFPicoReadBitCounter,&l_bPicoReadStatus,&l_bRFReceiveEOF,&l_bBitToReceive);
for(l_indSlot = 0; l_indSlot <= l_iMaxSlot;)
{
if (l_bStatus == ERR_NOCARD) // NO CHIP IN MASK
{
// SEND EOF : MOVE TO NEXT SLOT
if (l_iMaxSlot == 0) goto lbl_Retry;
else
{
v_fnSendBuffer(0,0,0,&l_abBuffer[0],p_pStructReader);
l_bStatus=b_fnReceiveBuffer(_CHECKCRC,&l_abBuffer[0],p_pStructReader,&l_wRFPicoReadByteCounter,&l_bRFPicoReadBitCounter,&l_bPicoReadStatus,&l_bRFReceiveEOF,&l_bBitToReceive);
}
// INCREMENT SLOT INDEX
l_indSlot++;
}
else
if (l_bStatus == ERR_NO_ERROR) // 1 CHIP IN SLOT
{
// PUT UID ON BUFFER
memcpy(&p_abUID[0],&l_abBuffer[2],8);
;
*p_bUIDLength=8;
goto lbl_Stayquiet;
}
else
if (l_bStatus == ERR_COLL || l_bStatus == ERR_CRC) // COLLISION DETECTED
{
// EXTRACT MASK - ONE BYTE
memcpy(l_abMask,&l_abBuffer[2],1);
l_abMask[0]&=0x01;
// EXECUTE INVENTORY WITH MASK
if (l_iMaxSlot != 0) l_iMaskLength = 4;
else l_iMaskLength = 1;
if (b_fnISO15695_MaskedInventory(l_bInvFlag, p_pStructReader->s_bRAnticolOpt2, l_iMaskLength, l_abMask,&l_abBuffer[0],p_pStructReader,&l_wRFPicoReadByteCounter, &l_bRFPicoReadBitCounter, &l_bPicoReadStatus,&l_bRFReceiveEOF) )
{
memcpy(&p_abUID[0],&l_abBuffer[2],8);
*p_bUIDLength=8;
goto lbl_Stayquiet;
}
else
{
// INCREMENT SLOT INDEX
l_indSlot++;
if (l_iMaxSlot != 0)
{
for(l_bDelay=15;l_bDelay>0;l_bDelay--) delay_us(200); // delay 3 ms
v_fnSendBuffer(0,0,0,&l_abBuffer[0],p_pStructReader);
l_bStatus=b_fnReceiveBuffer(_CHECKCRC,&l_abBuffer[0],p_pStructReader,&l_wRFPicoReadByteCounter,&l_bRFPicoReadBitCounter,&l_bPicoReadStatus,&l_bRFReceiveEOF,&l_bBitToReceive);
}
}
}
else goto lbl_Retry;
}
goto lbl_Retry;
lbl_Stayquiet:
// SEND STAY QUIET COMMAND IF REQUESTED
if (p_pStructReader->s_bRAnticolOpt0 & ISO150_STAYQUIET)
{
l_abBuffer[0]=_ISO15_SQFLAG;
l_abBuffer[1]=_ISO15_STAYQUIET;
memcpy(&l_abBuffer[0],&p_abUID[0],8);
v_fnSendBuffer(_SENDCRC,10,0,&l_abBuffer[0],p_pStructReader);
}
p_pStructReader->s_bRTimeoutUsed=p_pStructReader->s_bRTimeoutDefault;
// ANTICOLLISION OK EVEN IF STAY QUIET COMMAND DIDN'T WORK
return TRUE;
lbl_Retry:
if(l_bRetry--)
{
if(p_pStructReader->s_bRAnticolOpt1&ISO151_RESET)
{
v_fnCS_reset();
v_fnSPI_SendByte(P0_REG_NO_RST | P0_PAGE_SELECT_1);
// DELAY 2MS
for(l_bDelay=10;l_bDelay>0;l_bDelay--) delay_us(200);
v_fnCS_reset();
v_fnSPI_SendByte(P0_REG_NO_RST | P0_PAGE_SELECT_1 | P0_RFON);
}
goto lbl_Loop;
}
return FALSE;
}
//#endif
//-----------------------------------------------------------------------------
// Function name : b_fnISO15695_MaskedInventory(BYTE p_bInvFlag, BYTE p_bAFI,
// BYTE p_bMaskLength, BYTE *p_abMask)
//-----------------------------------------------------------------------------
// Description : Use masked inventory command to extract one card from x card
//
// IN : p_bInvFlag : Inventory flags byte (AFI used & nb slots)
// p_bAFI : Application type
// p_bMaskLength : Mask length (bits)
// p_abMask : Mask used
// p_pabBuffer : Pointer to the Buffer for RFCom
//
//
// OUT : - none -
//
// RETURN : true 1 if a card is selected.
// false 0 no card selected.
//
// Notes : - none -
//-----------------------------------------------------------------------------
unsigned char b_fnISO15695_MaskedInventory(unsigned char p_bInvFlag, unsigned char p_bAFI, unsigned char p_bMaskLength, unsigned char *p_abMask, unsigned char* p_pabBuffer,StructReader* p_pStructReader,unsigned short* p_pwRFPicoReadByteCounter, unsigned char* p_pbRFPicoReadBitCounter, unsigned char* p_pbPicoReadStatus, unsigned char* p_pbRFReceiveEOF)
{
unsigned char l_bNumBytes;
unsigned char l_bStatus;
unsigned char l_btry=0;
unsigned char l_bdelay;
unsigned char l_bBitToReceive;
// MASKED INVENTORY COMMAND - GET BUFFER SIZE
l_bNumBytes = (p_bMaskLength) / 8;
if (p_bMaskLength % 8) l_bNumBytes++;
lbl_RecursiveCall:
// MASKED INVENTORY COMMAND - COMMAND GENERATION
p_pabBuffer[0]= _ISO15_INVFLAG + p_bInvFlag;
p_pabBuffer[1]= _ISO15_INVENTORY;
p_pabBuffer[2]= p_bAFI;
p_pabBuffer[3]= p_bMaskLength;
memcpy(&p_pabBuffer[4], p_abMask, l_bNumBytes);
for(l_bdelay=15;l_bdelay>0;l_bdelay--) delay_us(200); // delay 3 ms
// MASKED INVENTORY COMMAND - COMMAND EXECUTION
v_fnSendBuffer(_SENDCRC,4+l_bNumBytes,0,p_pabBuffer,p_pStructReader);
l_bStatus=b_fnReceiveBuffer(_CHECKCRC,p_pabBuffer,p_pStructReader,p_pwRFPicoReadByteCounter,p_pbRFPicoReadBitCounter,p_pbPicoReadStatus,p_pbRFReceiveEOF,&l_bBitToReceive);
// STATUS WORD INTERPRETATION
if (l_bStatus == ERR_NOCARD) // NO CHIP IN MASK
{
//ERROR ON COMMAND
if(l_btry==2) return FALSE;
else
{
l_btry++;
if ((l_btry==1) && ((p_bMaskLength % 8)!=0))
{
if (bit_testChar(&p_abMask[l_bNumBytes-1],((p_bMaskLength % 8)-2))) bit_clearChar(&p_abMask[l_bNumBytes-1],((p_bMaskLength % 8)-2));
else bit_setChar(&p_abMask[l_bNumBytes-1],((p_bMaskLength % 8)-2));
}
else if (l_btry==1)
{
if (bit_testChar(&p_abMask[l_bNumBytes-2],7)) bit_clearChar(&p_abMask[l_bNumBytes-2],7);
else bit_setChar(&p_abMask[l_bNumBytes-2],7);
}
goto lbl_RecursiveCall;
}
}
else
if (l_bStatus == ERR_NO_ERROR) return TRUE;// 1 CHIP IN MASK
else
if (l_bStatus == ERR_COLL || l_bStatus == ERR_CRC) // COLLISION DETECTED
{
l_btry=0;
// TEST COMMAND PARAMETERS
if (p_bInvFlag & 0x20) // INVENTORY ON 1 SLOT
{
// INCREMENT MASK SIZE
p_bMaskLength++;
// LIMIT INVENTORY RECURSIVITY
if (p_bMaskLength > 64) return FALSE;
}
else // INVENTORY ON 16 SLOT
{
// INCREMENT MASK SIZE
p_bMaskLength += 4;
// LIMIT INVENTORY RECURSIVITY
if (p_bMaskLength > 60) return FALSE;
}
// GET NEW MASK LENGTH IN BYTES
l_bNumBytes = (p_bMaskLength) / 8;
if (p_bMaskLength % 8) l_bNumBytes++;
// EXTRACT MASK FOR NEXT ITERATION
memcpy(p_abMask, &p_pabBuffer[2], l_bNumBytes);
if ((p_bMaskLength % 8) == 1) p_abMask[l_bNumBytes-1]&=0x01;
if ((p_bMaskLength % 8) == 2) p_abMask[l_bNumBytes-1]&=0x03;
if ((p_bMaskLength % 8) == 3) p_abMask[l_bNumBytes-1]&=0x07;
if ((p_bMaskLength % 8) == 4) p_abMask[l_bNumBytes-1]&=0x0F;
if ((p_bMaskLength % 8) == 5) p_abMask[l_bNumBytes-1]&=0x1F;
if ((p_bMaskLength % 8) == 6) p_abMask[l_bNumBytes-1]&=0x3F;
if ((p_bMaskLength % 8) == 7) p_abMask[l_bNumBytes-1]&=0x7F;
// EXECUTE INVENTORY WITH MASK
goto lbl_RecursiveCall;
}
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -