⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prd_iso15693_anticollision.c

📁 读RF卡的源代码
💻 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 + -