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

📄 armspi.c

📁 用ARM的LPC2200来 SPI通信方式下读卡器驱动程序 其读卡器为FM172
💻 C
📖 第 1 页 / 共 4 页
字号:
   int8  complete= 0;
   int8  i       = 0;
   int8  byteOffset= 0;
   uint8 snr_crc;
   uint8 snr_check;
   uint8 dummyShift1;       // dummy byte for snr shift
   uint8 dummyShift2;       // dummy byte for snr shift   
 
   //************* Initialisation ******************************
   FM1702PcdSetTmo(106);    
   memcpy1(snr_in,snr,4);   
   
   WriteIO(RegDecoderControl,0x28); 
   ClearBitMask(RegControl,0x08);   
      
   //************** Anticollision Loop ***************************
   complete = 0;	
//   bcnt = 0;  
   while (!complete && (status == MI_OK) )	
   {
      ResetInfo(MInfo);           
      WriteIO(RegChannelRedundancy,0x03); 
      nbits = bcnt % 8;   // remaining number of bits
      if (nbits)
      {
         WriteIO(RegBitFraming,nbits << 4 | nbits); // TxLastBits/RxAlign auf nb_bi
         nbytes = bcnt / 8 + 1;   
         // number of bytes known

         // in order to solve an inconsistency(矛盾) in the anticollision sequence
         // (will be solved soon), the case of 7 bits has to be treated in a
         // separate way - please note the err data sheet
         if (nbits == 7)
         {
            MInfo.cmd = PICC_ANTICOLL1;   // pass command flag to ISR        
            WriteIO(RegBitFraming,nbits); // reset RxAlign to zero
         }
      } 
      else
      {
         nbytes = bcnt / 8;
      }

      MSndBuffer[0] = PICC_ANTICOLL1;  
      MSndBuffer[1] = 0x20 + ((bcnt/8) << 4) + nbits; //number of bytes send
               
      for (i = 0; i < nbytes; i++)  // Sende Buffer beschreiben
      {
         MSndBuffer[i + 2] = snr_in[i];
      }
      MInfo.nBytesToSend   = 2 + nbytes;   
 
      status = FM1702PcdCmd(PCD_TRANSCEIVE,MSndBuffer, MRcvBuffer, &MInfo);   
      if (nbits == 7)
      {
         // reorder received bits
         dummyShift1 = 0x00;
         for (i = 0; i < MInfo.nBytesReceived; i++)
         {
            dummyShift2 = MRcvBuffer[i];
            MRcvBuffer[i] = (dummyShift1 >> (i+1)) | (MRcvBuffer[i] << (7-i));
            dummyShift1 = dummyShift2;
         }
         MInfo.nBitsReceived -= MInfo.nBytesReceived; // subtract received parity bits
         // recalculation of collision position
         if ( MInfo.collPos ) MInfo.collPos += 7 - (MInfo.collPos + 6) / 9;
      }
         
      if ( status == MI_OK || status == MI_COLLERR)    // no other occured
      {
         // R e s p o n s e   P r o c e s s i n g   
         if ( MInfo.nBitsReceived != (40 - bcnt) ) 
         {                     // not 5 bytes answered
            status = MI_BITCOUNTERR; // Exit with error
         } 
         else 
         {
            byteOffset = 0;
            if( nbits != 0 ) // last byte was not complete
            {
                snr_in[nbytes - 1] = snr_in[nbytes - 1] | MRcvBuffer[0];
                byteOffset = 1;
            }

            for ( i =0; i < (4 - nbytes); i++)    
            {
               snr_in[nbytes + i] = MRcvBuffer[i + byteOffset];
            }
  
            if (status != MI_COLLERR ) 
            {
               // SerCh check
               snr_crc = snr_in[0] ^ snr_in[1] ^ snr_in[2] ^ snr_in[3];
               snr_check = MRcvBuffer[MInfo.nBytesReceived - 1];
               if (snr_crc != snr_check)	
               {
                  status = MI_SERNRERR;
               } 
               else   			
               {
                  complete = 1;
               }
            }
            else                   // collision occured
            {
               bcnt = bcnt + MInfo.collPos - nbits;
               status = MI_OK;
            }
         }
      }
   }
   if (status == MI_OK)
   {
      // transfer snr_in to snr
      memcpy1(snr,snr_in,4);
   }
   else
   {
      memcpy1(snr,_0000,4);
   }

   //----------------------Einstellungen aus Initialisierung ruecksetzen 
   ClearBitMask(RegDecoderControl,0x20); // ZeroAfterColl disable
   
   return status;  
}

///////////////////////////////////////////////////////////////////////
//          M I F A R E    S E L E C T 
// for std. select
///////////////////////////////////////////////////////////////////////
int8 FM1702PiccSelect(uint8 *snr,   uint8 *sak)
{
   int8  status = MI_OK; 
   FM1702PcdSetTmo(106);
   WriteIO(RegChannelRedundancy,0x0F); 
   ClearBitMask(RegControl,0x08);    // disable crypto 1 unit

   //************* Cmd Sequence ********************************** 
   ResetInfo(MInfo);   
   MSndBuffer[0] = PICC_SELECT1;  
   MSndBuffer[1] = 0x70;         // number of bytes send
   
   memcpy1((uint8*)(MSndBuffer + 2),snr,4);
   MSndBuffer[6] = MSndBuffer[2] ^ MSndBuffer[3]^ MSndBuffer[4]^ MSndBuffer[5];                 
   MInfo.nBytesToSend   = 7;
   status = FM1702PcdCmd(PCD_TRANSCEIVE, MSndBuffer, MRcvBuffer,&MInfo);
   *sak = 0;   
   if (status == MI_OK)    // no timeout occured
   {
      if (MInfo.nBitsReceived != 8)    // last byte is not complete
      {
         status = MI_BITCOUNTERR;
      }
      else
      {
	 *sak = MRcvBuffer[0];
         memcpy1(MLastSelectedSnr,snr,4);       
      }	
   }
  
   return status;
}
///////////////////////////////////////////////////////////////////////
//                      C O D E   K E Y S 
///////////////////////////////////////////////////////////////////////
int8 FM1702HostCodeKey(  uint8 *uncoded,  uint8 *coded) 
{
   uint8  cnt = 0;
   uint8  ln  = 0;     // low nibble
   uint8  hn  = 0;     // high nibble
   
   for (cnt = 0; cnt < 6; cnt++)
   {
      ln = uncoded[cnt] & 0x0F;
      hn = uncoded[cnt] >> 4;
      coded[cnt * 2 + 1] = (~ln << 4) | ln;
      coded[cnt * 2 ] = (~hn << 4) | hn;

   }
   return MI_OK;
}
/*---------------------------------------------------------------------
//          E E P R O M   M A S T E R   K E Y   L O A D 
---------------------------------------------------------------------*/
int8 FM1702PcdLoadKeyE2(uint8 key_type, uint8 sector,uint8 *uncoded_keys)

{
   int8  status = MI_OK;
   uint16  e2addr = 0x80 + sector * 0x18;  
   uint8  keycoded[12];

   if (key_type == PICC_AUTHENT1B)
      e2addr += 12;  
   
   FlushFIFO();    // empty FIFO
   ResetInfo(MInfo);

   FM1702HostCodeKey(uncoded_keys,keycoded);
    MSndBuffer[0]=e2addr&0xff;
    MSndBuffer[1]=(e2addr&0xff00)>>8;
   memcpy1((uint8*)&MSndBuffer[2],keycoded,12); // write 12 bytes of coded keys
   MInfo.nBytesToSend   = 14;
   // write load command
   status = FM1702PcdCmd(PCD_WRITEE2,MSndBuffer,MRcvBuffer,&MInfo);  
   return status;
}

///////////////////////////////////////////////////////////////////////
//                  A U T H E N T I C A T I O N   
//             W I T H   K E Y S   F R O M   E 2 P R O M
///////////////////////////////////////////////////////////////////////
int8 FM1702PiccAuthE2( uint8 auth_mode, uint8 *snr,  uint8 key_sector, uint8 block)   
{
   int8  status = MI_OK;
   uint16 e2addr;
    
   uint8 *e2addrbuf = (uint8*)&e2addr;
    e2addr = 0x80 + key_sector * 0x18;
    
   if (auth_mode == PICC_AUTHENT1B)
      e2addr += 12; 
      
   e2addrbuf = (uint8*)&e2addr;
    
   FlushFIFO();    // empty FIFO
   ResetInfo(MInfo);

   memcpy1((uint8*)MSndBuffer,e2addrbuf,2); 
   MSndBuffer[2] = MSndBuffer[0];          
   MSndBuffer[0] = MSndBuffer[1];  
   MSndBuffer[1] = MSndBuffer[2];
   MInfo.nBytesToSend   = 2;
   
   if ((status=FM1702PcdCmd(PCD_LOADKEYE2,MSndBuffer,MRcvBuffer,&MInfo)) == MI_OK)
   {      
     
      status = FM1702PiccAuthState(auth_mode,snr,block);  
   }
   return status;
}                        

///////////////////////////////////////////////////////////////////////
//          M I F A R E      A U T H E N T I C A T I O N
//  直接密钥验证    
///////////////////////////////////////////////////////////////////////
int8 FM1702PiccAuthKey(uint8 auth_mode,  uint8 *snr, uint8 *key_addr,uint8 block)            
{
   int8    status = MI_OK;
   uint8   keycoded[12];

   FM1702HostCodeKey(key_addr,keycoded);
      
   FlushFIFO();    // empty FIFO
   ResetInfo(MInfo);
   memcpy1((uint8*)MSndBuffer,keycoded,12);                  // write 12 bytes of the key
   MInfo.nBytesToSend = 12;
   if ((status=FM1702PcdCmd(PCD_LOADKEY,MSndBuffer,MRcvBuffer,&MInfo)) == MI_OK)
   {      
      status = FM1702PiccAuthState(auth_mode,snr,block); 
   }
   return status;
}

///////////////////////////////////////////////////////////////////////
//        A U T H E N T I C A T I O N   S T A T E S
///////////////////////////////////////////////////////////////////////
int8 FM1702PiccAuthState( uint8 auth_mode, uint8 *snr, uint8 block)
{
   int8  status = MI_OK;
   
   status = ReadIO(RegErrorFlag); 
                                     
   if (status != MI_OK)
   {
      if (status & 0x40)            // key error flag set
         status = MI_KEYERR;    
      else
         status = MI_AUTHERR;      
   }
   else
   {
      MSndBuffer[0] = auth_mode;       
      MSndBuffer[1] = block;            
      memcpy1((uint8*)(MSndBuffer + 2),snr,4); 
      ResetInfo(MInfo);
      MInfo.nBytesToSend = 6;
      if ((status = FM1702PcdCmd(PCD_AUTHENT1,MSndBuffer, MRcvBuffer, &MInfo)) == MI_OK)
      {
         if (ReadIO(RegSecondaryStatus) & 0x07)
         {
            status = MI_BITCOUNTERR;	
         }
         else
         {
            ResetInfo(MInfo);
            MInfo.nBytesToSend = 0;
            if ((status = FM1702PcdCmd(PCD_AUTHENT2,MSndBuffer,MRcvBuffer,&MInfo)) == MI_OK) 
            {
               if ( ReadIO(RegControl) & 0x08 ) 
	       	
               {
                   status = MI_OK;
               }
               else
               {
                   status = MI_AUTHERR;
               }
            }
         }
      }
   }
   return status;
}

///////////////////////////////////////////////////////////////////////
//          M I F A R E   R E A D   
///////////////////////////////////////////////////////////////////////
int8 FM1702PiccRead(  uint8 block,
                  uint8 *_data)
{
   int8  status = MI_OK;
    uint8 _16ge0[17]="0000000000000000";
   FlushFIFO();    // empty FIFO

   FM1702PcdSetTmo(3);     // long timeout 

   WriteIO(RegChannelRedundancy,0x0F); 
   
   // ************* Cmd Sequence ********************************** 
   ResetInfo(MInfo);   
   MSndBuffer[0] = PICC_READ; 
   MSndBuffer[1] = block;	
   MInfo.nBytesToSend   = 2;   
   status = FM1702PcdCmd(PCD_TRANSCEIVE,MSndBuffer, MRcvBuffer, &MInfo);
   if (status != MI_OK)
   {
      if (status != MI_NOTAGERR ) // no timeout occured
      {
         if (MInfo.nBitsReceived == 4)  // NACK

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -