#include "includes.h" 


// *****************************************************************
// PcdRequest
// prikaz REQUEST - detekce karty v poli a identifikace kodem ATQA
// *****************************************************************
tUInt PcdRequest(unsigned char req_code, unsigned char *pTagType)
{
   tUInt status;   
  
	 
   struct TranSciveBuffer MfComData;
   struct TranSciveBuffer *pi;
   pi = &MfComData;

   WriteRawRC(RegChannelRedundancy,0x03);		// CRC OFF
   ClearBitMask(RegControl,0x08);				// CRYPTO OFF
   WriteRawRC(RegBitFraming,0x07);
   
   PcdSetTmo(4);				// TIMEOUT 5MS
   
   MfComData.MfCommand = PCD_TRANSCEIVE;
   MfComData.MfLength  = 1;
   MfComData.MfData[0] = req_code;

   status = PcdComTransceive(pi);
   
   if (status != MIFARE_NOTAG_ERROR)
    {    
      if (MfComData.MfLength != 0x10)
       {
	     status = MIFARE_BITCOUNT_ERR;   
	   }
    }

   *pTagType     = MfComData.MfData[0];
   *(pTagType+1) = MfComData.MfData[1];
   

   if (status == NO_ERROR)
    {
      gCard.card_type[0] = MfComData.MfData[0];		// zde je ulozen ATQA karty 
      gCard.card_type[1] = MfComData.MfData[1];		// jsou to 2 bajty 
	  
	  return READER_TAG_OK;
	}
   else
    {
	  return status;
	}
}



// *****************************************************************
// PcdAnticoll
// antikolizni smycka - nacteni UID karty
// *****************************************************************
tUInt PcdAnticoll(tUChar mode, unsigned char *pSnr)
{
    tUInt status;
    unsigned char i;
    unsigned char ucBits;
    unsigned char ucBytes;
    unsigned char snr_check = 0;
    unsigned char ucCollPosition = 0;
    unsigned char ucTemp;
    unsigned char ucSNR[5] = {0, 0, 0, 0 ,0};
   
    struct TranSciveBuffer MfComData;
    struct TranSciveBuffer *pi;
    pi = &MfComData;

    WriteRawRC(RegDecoderControl,0x28);
    ClearBitMask(RegControl,0x08);					// CRYPTO OFF
    WriteRawRC(RegChannelRedundancy,0x03);			// CRC OFF
    PcdSetTmo(4);
 
    do
    {
        ucBits = (ucCollPosition) % 8;
        if (ucBits != 0)
         {
          ucBytes = ucCollPosition / 8 + 1;
          WriteRawRC(RegBitFraming, (ucBits << 4) + ucBits);
         }
        else
         {
          ucBytes = ucCollPosition / 8;
         }
        
        MfComData.MfCommand = PCD_TRANSCEIVE;
        MfComData.MfData[0] = mode;					// cascade level
        MfComData.MfData[1] = 0x20 + ((ucCollPosition / 8) << 4) + (ucBits & 0x0F);
        
		for (i=0; i<ucBytes; i++)
         {
           MfComData.MfData[i + 2] = ucSNR[i];
         }
		MfComData.MfLength = ucBytes + 2;

        status = PcdComTransceive(pi);
        ucTemp = ucSNR[(ucCollPosition / 8)];
        
		if (status == MIFARE_ANTICOLL_ERROR)
         {
           for (i=0; i < 5 - (ucCollPosition / 8); i++)
            {
              ucSNR[i + (ucCollPosition / 8)] = MfComData.MfData[i+1];
            }
           ucSNR[(ucCollPosition / 8)] |= ucTemp;
           ucCollPosition = MfComData.MfData[0];
         }
		 
		else if (status == NO_ERROR)
         {
           for (i=0; i < (MfComData.MfLength / 8); i++)
            {
                 ucSNR[4 - i] = MfComData.MfData[MfComData.MfLength/8 - i - 1];
            }
            ucSNR[(ucCollPosition / 8)] |= ucTemp;
         }
    
	} while (status == MIFARE_ANTICOLL_ERROR);
                        
                        
    if (status == NO_ERROR)
     {
       for (i=0; i<4; i++)
        {   
          *(pSnr+i)  = ucSNR[i];
          snr_check ^= ucSNR[i];
        }
    
	   if (snr_check != ucSNR[i])
        {
	      status = READER_TAG_ERROR;    
	    }
     }
    
    ClearBitMask(RegDecoderControl,0x20);
    
	return status;
}


// *****************************************************************
// PcdSelect
// vyber karty prikazem SELECT a identifikace karty kodem SAK
// *****************************************************************
tUInt PcdSelect(tUChar mode, unsigned char *pSnr, unsigned char *pSize)
{
    unsigned char i;
    tUInt status;
    unsigned char snr_check;
    struct TranSciveBuffer MfComData;
    struct TranSciveBuffer *pi;
    
	snr_check = 0;
	pi = &MfComData;
    pSize = pSize;

    WriteRawRC(RegChannelRedundancy,0x0F);		// CRC ON
    ClearBitMask(RegControl,0x08);				// CRYPTO OFF
    PcdSetTmo(4);
    
    MfComData.MfCommand = PCD_TRANSCEIVE;
    MfComData.MfLength  = 7;
    MfComData.MfData[0] = mode;			// anticolizni mod- cascade level
    MfComData.MfData[1] = 0x70;
    
	for (i=0; i<4; i++)
     {
       snr_check ^= *(pSnr+i);
       MfComData.MfData[i+2] = *(pSnr+i);
     }
    MfComData.MfData[6] = snr_check;

    status = PcdComTransceive(pi);
    if (status == NO_ERROR)
     {
       if (MfComData.MfLength != 0x08)
        {
		  status = MIFARE_BITCOUNT_ERR;
		}
       else
        {
		  *pSize = MfComData.MfData[0];
		}
    }

    return status;
}


// *****************************************************************
// ChangeCodeKey
// prekodovani pristupovych klicu do pozadovaneho formatu
// *****************************************************************
#if defined INTERFACE_RD3 && defined  READER_MIFARE
tUInt ChangeCodeKey(unsigned char *pUncoded,unsigned char *pCoded)
{
   unsigned char cnt=0;
   unsigned char ln=0;
   unsigned char hn=0;

   for (cnt=0; cnt<6; cnt++)
   {
      ln = pUncoded[cnt] & 0x0F;
      hn = pUncoded[cnt] >> 4;
      pCoded[cnt*2+1] = (~ln<<4) | ln;
      pCoded[cnt*2]   = (~hn<<4) | hn;
   }
   return NO_ERROR;
}
#endif


// *****************************************************************
// PcdLoadKey
// nahraje pristupove klice do RAM
// *****************************************************************
#if defined INTERFACE_RD3 && defined  READER_MIFARE
tUInt PcdLoadKey(unsigned char *pKeys)
{
  tUInt status;
	
  struct TranSciveBuffer MfComData;
  struct TranSciveBuffer *pi;
  pi = &MfComData;

  PcdSetTmo(106);
  MfComData.MfCommand = PCD_LOADKEY;
  MfComData.MfLength  = 12;
  my_memcpy(&MfComData.MfData[0], pKeys, 12);    

  status = PcdComTransceive(pi);

  return status;
}
#endif


// *****************************************************************
// PcdAuthState
// autentizace pristupu do sektoru
// *****************************************************************
#if defined INTERFACE_RD3 && defined  READER_MIFARE
tUInt PcdAuthState(unsigned char auth_mode, unsigned char block_addr, unsigned char *pSnr)
{
  tUInt status;
  tUChar temp;
	
  struct TranSciveBuffer MfComData;
  struct TranSciveBuffer *pi;
  pi = &MfComData;


    WriteRawRC(RegChannelRedundancy,0x0F);			// CRC ON
    PcdSetTmo(106);
	
	// autentizace PART 1
    MfComData.MfCommand = PCD_AUTHENT1;
    MfComData.MfLength  = 6;
    MfComData.MfData[0] = auth_mode;
    MfComData.MfData[1] = block_addr;				// fyzicka adresa bloku
    
	MfComData.MfData[2] = *(tUChar*)&pSnr[0];    
    MfComData.MfData[3] = *(tUChar*)&pSnr[1];    
    MfComData.MfData[4] = *(tUChar*)&pSnr[2];    
    MfComData.MfData[5] = *(tUChar*)&pSnr[3];          
    
	status = PcdComTransceive(pi);
	if (status == NO_ERROR)
    {
		if (ReadRawRC(RegSecondaryStatus) & 0x07) 		// neprijat cely bajt
         { 
		  status = MIFARE_BITCOUNT_ERR; 
		 }
        else											// prijat cely bajt, pokracovat
         {
           MfComData.MfCommand = PCD_AUTHENT2;
           MfComData.MfLength  = 0;
		   status = PcdComTransceive(pi);

		   if (status == NO_ERROR)
            {
	    	 if (ReadRawRC(RegControl) & 0x08)
              {
			    status = NO_ERROR;  
			  }
             else
              {
			    status = MIFARE_AUTH_ERR;
			  }
           }
         }
    }

// po antentizaci chvili pockat
  wait_ms(1);	
  
  
  return status;
}
#endif


// *****************************************************************
// PcdRead 
// cteni DATA bloku
// *****************************************************************
#if defined INTERFACE_RD3 && defined  READER_MIFARE
tUInt PcdRead(unsigned char block_addr,unsigned char *pReaddata)
{
  tUInt status;
  struct TranSciveBuffer MfComData;
  struct TranSciveBuffer *pi;
  pi = &MfComData;

  my_memset (&MfComData, 0, sizeof(MfComData));

  PcdSetTmo(4);
  WriteRawRC(RegChannelRedundancy,0x0F);			// NASTAVIT GENEROVANI CRC

  MfComData.MfCommand = PCD_TRANSCEIVE;
  MfComData.MfLength  = 2;
  MfComData.MfData[0] = PICC_READ;
  MfComData.MfData[1] = block_addr;

  status = PcdComTransceive(pi);
  if (status == MIFARE_NO_ERROR)
   {	
 	 if (MfComData.MfLength != 0x80)				// nacteno 16 bajtu? (16*8=128bitu)
      {   
		if (MfComData.MfLength == 0x04)
		  status = MIFARE_READ_ERR;
		else
		  status = MIFARE_BITCOUNT_ERR;   
	  }
     else
      {  
		my_memcpy( pReaddata, &MfComData.MfData[0], 16); 
	  }
   }
   
   return status;
   
}
#endif


// *****************************************************************
// PcdWrite
// zapis do DATA bloku
// *****************************************************************
#if defined INTERFACE_RD3 && defined  READER_MIFARE
tUInt PcdWrite(unsigned char addr,unsigned char *pWritedata)
{
    tUInt status;
	tUChar temp;
    struct TranSciveBuffer MfComData;
    struct TranSciveBuffer *pi;
    pi = &MfComData;
    
	my_memset (&MfComData, 0, sizeof(MfComData));
	
    PcdSetTmo(4); 						
    WriteRawRC(RegChannelRedundancy,0x0F);			// NASTAVIT GENEROVANI CRC
		    
	MfComData.MfCommand = PCD_TRANSCEIVE;
    MfComData.MfLength  = 2;
    MfComData.MfData[0] = PICC_WRITE;
    MfComData.MfData[1] = addr;

    status = PcdComTransceive(pi);
    if (status != MIFARE_NOTAG_ERROR)
	 {
       if (MfComData.MfLength != 4)
        {
	     status=MIFARE_BITCOUNT_ERR;
	    }
       else
        {
		  MfComData.MfData[0] &= 0x0F;
		  temp = MfComData.MfData[0];
          switch (temp)
            {
              case 0x00:
                 status = MIFARE_AUTH_ERR;
                 break;
				 
              case 0x0A:
                 status = MIFARE_NO_ERROR;
                 break;
				 
              default:
                 status = MIFARE_CODE_ERR;
                 break;
           }
        }
    }
 
 
   if (status == MIFARE_NO_ERROR)
    {
      PcdSetTmo(4);         
	  MfComData.MfCommand = PCD_TRANSCEIVE;
      MfComData.MfLength  = 16;
      my_memcpy(&MfComData.MfData[0], pWritedata, 16);


      status = PcdComTransceive(pi);
      if (status != MIFARE_NOTAG_ERROR)
       {
		  MfComData.MfData[0] &= 0x0F;
		  temp = MfComData.MfData[0];
          switch (temp)
          {
            case 0x00:
              status = MIFARE_WRITE_ERR;
            break;
				  
            case 0x0A:
              status = MIFARE_NO_ERROR;
            break;
				  
            default:
              status = MIFARE_CODE_ERR;
            break;
           }
        }
    }
    return status;
}
#endif


// *****************************************************************
// ValueBlockChangeOrder 
// prohodi poradi bajtu v poli MSB->LSB
// *****************************************************************
#if defined INTERFACE_RD3 && defined  READER_MIFARE
void ValueBlockChangeOrder( tUChar *data)
{
 tUChar temp[4];
 tUChar temp2;
   
 my_memcpy( &temp[0], &data[0] , 4 );		// zkopirovat 4 bajty VALUE
	
 // preskladat prvni kopii VALUE bloku
 temp2 = temp[0];
 temp[0] =  temp[3];
 temp[3] =  temp2;
 
 temp2 = temp[1];
 temp[1] =  temp[2];
 temp[2] =  temp2;

 my_memcpy( &data[0], &temp[0], 4 );
    
}
#endif
			
			
	
// *****************************************************************
// TranscodeValueBlock 
// prekodovani hodnoty VALUE bloku do pozadovaneho formatu 
// *****************************************************************	
#if defined INTERFACE_RD3 && defined  READER_MIFARE
void TranscodeValueBlock( tUChar* ptrdata, tUChar adr)
{
 tUChar temp[16];
 tUChar temp2;
 
 // data ve VALUE bloku jsou ulozena LSB byte na nejnizsi adrese, tedy opacne nezmame v bufferu
 my_memcpy( &temp[0], &ptrdata[0] , 4 );		// zkopirovat 4 bajty VALUE

 // preskladat prvni kopii VALUE bloku
 temp2 = temp[0];
 temp[0] =  temp[3];
 temp[3] =  temp2;
 
 temp2 = temp[1];
 temp[1] =  temp[2];
 temp[2] =  temp2;


 // druha kopie je inverzni
 temp[4] = ~temp[0];
 temp[5] = ~temp[1];
 temp[6] = ~temp[2];
 temp[7] = ~temp[3];

  
 // treti kopie je normalni
 temp[8]  = temp[0];
 temp[9]  = temp[1];
 temp[10] = temp[2];
 temp[11] = temp[3];
 
 // 4 kopie adresy 
 temp[12] = adr;
 temp[13] = ~adr;
 temp[14] = adr;
 temp[15] = ~adr;

 my_memcpy( &ptrdata[0], &temp[0], 16 );		// zkopirovat blok zpet na src
   
}
#endif



// *****************************************************************
// PcdValue
// zapis do VALUE bloku - WRITE/INCREMENT/DECREMENT
// *****************************************************************
#if defined INTERFACE_RD3 && defined  READER_MIFARE
tUInt PcdValue(unsigned char dd_mode, unsigned char addr, tUChar *pData, tUChar byte_count)
{
    tUInt status;
    struct TranSciveBuffer MfComData;
    struct TranSciveBuffer *pi;
	tUChar temp;
	
    pi = &MfComData;

    my_memset (&MfComData, 0, sizeof(MfComData));


    PcdSetTmo(4);
    WriteRawRC(RegChannelRedundancy,0x0F);			// NASTAVIT GENEROVANI CRC
	
	// nejdrive se posle karte prikaz - operace s VALUE blokem (WRITE/INCREMENT/DECREMENT)
    MfComData.MfCommand = PCD_TRANSCEIVE;
    MfComData.MfLength  = 2;
    MfComData.MfData[0] = dd_mode;
    MfComData.MfData[1] = addr;

    wait_ms(2);	
    status = PcdComTransceive(pi);
    if (status != MIFARE_NOTAG_ERROR)
     {
       if (MfComData.MfLength != 4)
        {
	      status = MIFARE_BITCOUNT_ERR;   
		}
       else
        {
          MfComData.MfData[0] &= 0x0F;
		  temp = MfComData.MfData[0];
          switch (temp)
           {
              case 0x00:
                 status = MIFARE_AUTH_ERR;
              break;
              
			  case 0x0a:
                 status = MIFARE_NO_ERROR;
              break;
              
			  case 0x01:
                 status = MIFARE_VALUE_ERR;
                 break;
              
			  default:
                 status = MIFARE_CODE_ERR;
              break;
           }    // konec switch
        }		// konec else
     }			// konec if (status != MIFARE_NOTAG_ERROR)  

	
	 //  pokud probehne prikaz prace VALUE blokem bez chyby
	 // nasleduje odeslani 4-bajtove hodnoty VALUE v pripade WRITE, nebo velikosti incrementu/decrementu
     if (status == MIFARE_NO_ERROR)
      {
		PcdSetTmo(4);
        MfComData.MfCommand = PCD_TRANSCEIVE;
        
		// v pripade ze zapisujeme do VALUE bloku, musi se ukladat celych 16 bajtu ve stanovenem formatu
		// pro operace INCREMENT a DECREMENT jiz staci predat 4-bajtovou hodnotu 
		MfComData.MfLength  = byte_count;	
		
		// nakopirovat do bufferu k odeslani
		my_memcpy(&MfComData.MfData[0], &pData[0], MfComData.MfLength);
        
        status = PcdComTransceive(pi);
        if (status==MIFARE_NO_ERROR)
        {
          if (MfComData.MfLength != 4)
           {
			  status = MIFARE_BITCOUNT_ERR;   
		   }
          else
           { 
			  status = MIFARE_NO_ERROR;
		   }
        }		// konec if (status==MIFARE_NO_ERROR)
		
        else if(status == MIFARE_NOTAG_ERROR)
         {
		   status = MIFARE_NO_ERROR;    
		 }
        else
         {
		   status=READER_TAG_ERROR;     
		 } 
     }


	 // nasleduje prikaz TRANSFER ktery zapise zmenenou hodnotu z RAM na kartu
     if (status == MIFARE_NO_ERROR)
     {
		MfComData.MfCommand = PCD_TRANSCEIVE;
        MfComData.MfLength  = 2;
        MfComData.MfData[0] = PICC_TRANSFER;
        MfComData.MfData[1] = addr;

        status = PcdComTransceive(pi);
        if (status != MIFARE_NOTAG_ERROR)
         {
           if (MfComData.MfLength != 4)
            {
			  status = MIFARE_BITCOUNT_ERR;    
		    }
           else
            {
			  MfComData.MfData[0] &= 0x0F;
              /// !!!!!  NEVIm PROC V TOMTO MISTE KARTA HLASI NAK, NEVIM CO S TIM
			  // data  jsou predany do cteciho obvodu, a ceka se na vysledek prekopirovani na kartu
			  // melo by teoreticky vracet 0x0A jako ACK, ale nastava priznak CRCError, proto se vraci NAK
			  // mam vsak overeno ze data se fyzicky na kartu zapisou, presto je vracen NAK - mozna to kazi CLRC531
			  temp = MfComData.MfData[0];
              switch(temp)
               {
                  case 0x00:
                     status = MIFARE_AUTH_ERR;
                     break;
                  case 0x0a:
                     status = MIFARE_NO_ERROR;
                     break;
                  case 0x01:
                     status = MIFARE_VALUE_ERR;
                     break;
                  default:
                     //status = MIFARE_CODE_ERR;		// toto nedavat kvuli vyse popsanemu
                     break;
               }
			   
            }
        }
     }
	 
	 
     return status;
}
#endif


// *****************************************************************
// PcdRestore
// fce restore - nepouzito, neodladeno
// *****************************************************************
/*Int PcdRestore(unsigned char addr)
{
    tUInt status;
	tUChar temp;
    struct TranSciveBuffer MfComData;
    struct TranSciveBuffer *pi;
    pi = &MfComData;

    PcdSetTmo(4);
    MfComData.MfCommand = PCD_TRANSCEIVE;
    MfComData.MfLength  = 2;
    MfComData.MfData[0] = PICC_RESTORE;
    MfComData.MfData[1] = addr;

    status = PcdComTransceive(pi);
    if (status != MIFARE_NOTAG_ERROR)
     {
       if (MfComData.MfLength != 4)
        {
	      status = MIFARE_BITCOUNT_ERR;   
		}
       else
        {
          MfComData.MfData[0] &= 0x0F;
          temp = MfComData.MfData[0];
		  switch(temp)
           {
             case 0x00:
                 status = MIFARE_AUTH_ERR;
              break;
            
			 case 0x0A:
                 status = MIFARE_NO_ERROR;
              break;
            
			 case 0x01:
                 status = MIFARE_VALUE_ERR;
              break;
            
			 default:
                 status = MIFARE_CODE_ERR;
              break;
           }
        }
     }

     if (status == MIFARE_NO_ERROR)
      {
        PcdSetTmo(4);
        MfComData.MfCommand = PCD_TRANSCEIVE;
        MfComData.MfLength  = 4;
        MfComData.MfData[0] = 0;
        MfComData.MfData[1] = 0;
        MfComData.MfData[2] = 0;
        MfComData.MfData[3] = 0;
        
        status = PcdComTransceive(pi);
        if (status == MIFARE_NOTAG_ERROR)
         {
		  status = MIFARE_NO_ERROR;    
		 }
      }
     return status;
}
*/

/*
// *****************************************************************
// PcdTransfer
// fce transfer - nepouzito, neodladeno
// *****************************************************************
tUInt PcdTransfer(unsigned char addr)
{
    tUInt status;
	tUChar temp;
    struct TranSciveBuffer MfComData;
    struct TranSciveBuffer *pi;
    pi = &MfComData;

    PcdSetTmo(5);
    MfComData.MfCommand = PCD_TRANSCEIVE;
    MfComData.MfLength  = 2;
    MfComData.MfData[0] = PICC_TRANSFER;
    MfComData.MfData[1] = addr;

    status = PcdComTransceive(pi);
    if (status != MIFARE_NOTAG_ERROR)
     {
       if (MfComData.MfLength != 4)
        {
		  status = MIFARE_BITCOUNT_ERR;    
	    }
       else
        {
          MfComData.MfData[0] &= 0x0F;
		  temp = MfComData.MfData[0];
          switch (temp)
           {
             case 0x00:
                 status = MIFARE_AUTH_ERR;
                break;
             case 0x0A:
                 status = MIFARE_NO_ERROR;
                break;
             case 0x01:
                 status = MIFARE_VALUE_ERR;
                break;
             default:
                 status = MIFARE_CODE_ERR;
                break;
           }
        }
     }
     return status;
}
*/



// *****************************************************************
// PcdHalt
// zastavi praci s kartou
// *****************************************************************
char PcdHalt(void)
{
    tUInt status;
    struct TranSciveBuffer MfComData;
    struct TranSciveBuffer *pi;
    pi = &MfComData;

    status = MIFARE_NO_ERROR;
	
    MfComData.MfCommand = PCD_TRANSCEIVE;
    MfComData.MfLength  = 2;
    MfComData.MfData[0] = PICC_HALT;
    MfComData.MfData[1] = 0;

    status = PcdComTransceive(pi);
    if (status != MIFARE_NO_ERROR)
     {
       if (status==MIFARE_NOTAG_ERROR || status==MIFARE_READER_TIMEOUT_ERR)
        {
		  status = MIFARE_NO_ERROR;
		}
     }
    WriteRawRC(RegCommand,PCD_IDLE);
    return status;
}


// *****************************************************************
// PcdLoadKeyE2
// nahraje pristupove klice do EEPROM
// *****************************************************************
#if defined INTERFACE_RD3 && defined  READER_MIFARE
tUInt PcdLoadKeyE2(tUInt startaddr)
{
  tUInt status;
  struct TranSciveBuffer MfComData;
  struct TranSciveBuffer *pi;
  pi = &MfComData;


  MfComData.MfCommand=PCD_LOADKEYE2;
  MfComData.MfLength=2;
  MfComData.MfData[0]=startaddr&0xff;
  MfComData.MfData[1]=(startaddr>>8)&0xff;
  
  status=PcdComTransceive(pi);
  
  return status;
}
#endif


// *****************************************************************
// PcdReadE2
// cteno obsahu EEPROM
// *****************************************************************
#if defined INTERFACE_RD3 && defined  READER_MIFARE
tUInt PcdReadE2(tUInt startaddr, tUChar length, tUChar *readdata)
{
  tUChar i;
  tUInt status;
  
  struct TranSciveBuffer MfComData;
  struct TranSciveBuffer *pi;
  pi = &MfComData;

//--------------------------------------------------------------------
  // pred zahajenim pristupu k EEPROm je nutne zastavit CRYPTO!!
  PcdHalt();
  PCD_StopCrypto1();
  PcdAntennaOff();
  wait_ms(10);					// poctak dele nez 5ms
//--------------------------------------------------------------------


  MfComData.MfCommand = PCD_READE2;
  MfComData.MfLength = 3;
  MfComData.MfData[0] = startaddr&0xff;		// LSB
  MfComData.MfData[1] = (startaddr>>8);		// MSB
  MfComData.MfData[2] = length;
  
  status=PcdComTransceive(pi);
  if(status == MIFARE_NO_ERROR)
   {
     for(i=0; i<length; i++)
       {
         *(readdata+i)=MfComData.MfData[i];
       }
   }

 return status;

}
#endif


// *****************************************************************
// PcdWriteE2
// zapis do EEPROM
// *****************************************************************
#if defined INTERFACE_RD3 && defined  READER_MIFARE
tUInt PcdWriteE2(tUInt startaddr, tUChar length, tUChar *writedata)
{
  char i;
  tUInt status;
  struct TranSciveBuffer MfComData;
  struct TranSciveBuffer *pi;
  pi = &MfComData;


  MfComData.MfCommand = PCD_WRITEE2;
  MfComData.MfLength = length+2;
  MfComData.MfData[0] = startaddr&0x00ff;		// LSB
  MfComData.MfData[1] = startaddr>>8;			// MSB
 
  for(i=0; i<length; i++)
   {
     MfComData.MfData[i+2] = writedata[i];
   }
  
  status=PcdComTransceive(pi);
  return status;
  
}
#endif


