mfrc500.c

来自「mifarea卡程序mifarea卡程序mifarea卡程序」· C语言 代码 · 共 2,163 行 · 第 1/5 页

C
2,163
字号
}

/*
uchar M500GetHareVerNO(uchar* info)
{
   uchar status = MI_OK;
   FlushFIFO();
   ResetInfo(&MInfo);
   SndBuffer[0] = 0x00;
   SndBuffer[1] = 0x00;
   SndBuffer[2] = 16;
   MInfo.nBytesToSend   = 3;
   status = M500PcdCmd(PCD_READE2, SndBuffer, RcvBuffer, &MInfo);
   if (status == MI_OK)
   {
       memcpy(info,&RcvBuffer[8],4);
   }
   return status ;
}
*/
///////////////////////////////////////////////////////////////////////
//          C O N F I G   M F O U T   S E L E C T
///////////////////////////////////////////////////////////////////////
void M500PcdMfOutSelect(unsigned char type)
{
   WriteIO(RegMfOutSelect,type&0x7);
}

#if 0
uchar M500SendRead(char *tosend, uchar sendlen, char *read, uchar readlen)
{    
    uchar idata status = MI_OK;
    uchar idata tmp    = 0;

    FlushFIFO();
    M500PcdSetTmo(255);
    WriteIO(RegChannelRedundancy,0x0F);
    ResetInfo(&MInfo);
    /*
    SndBuffer[0] = PICC_READ;
    SndBuffer[1] = Address;
    */
    memcpy(SndBuffer, tosend, sendlen);
    MInfo.nBytesToSend = sendlen;
    status = M500PcdCmd(PCD_TRANSCEIVE, SndBuffer, RcvBuffer, &MInfo);
    if (status != MI_OK)
    {
        if (status != MI_NOTAGERR )
        {
            if (MInfo.nBitsReceived == 4)
            {
                RcvBuffer[0] &= 0x0f;
                if ((RcvBuffer[0] & 0x0a) == 0)
                {
                    status = MI_NOTAUTHERR;
                }
                else
                {
                    status = MI_CODEERR;
                }
            }
        }
    }
    else
    {
        /*
        if (MInfo.nBytesReceived != 16)
        {
            status = MI_BYTECOUNTERR;
        }
        else
        */
        {
            read[0] = MInfo.nBytesReceived;
            memcpy(read+1, RcvBuffer, MInfo.nBytesReceived);
        }
    }
    return status;
}
#endif

///////////////////////////////////////////////////////////////////////////////
//                  Interrupt Handler RC500
///////////////////////////////////////////////////////////////////////////////
void RC500ISR (void) interrupt 0 using 1    //Ext0 interrupt
{
#if 0
   static unsigned char idata irqBits;
   static unsigned char idata irqMask;
   static unsigned char idata nbytes;
   static unsigned char idata cnt;

   IE0 = 0; 	// Clear interrupt request flag

   if (MpIsrInfo && MpIsrOut && MpIsrIn)  // transfer pointers have to be set
                                          // correctly
   {
      while( ReadIO(RegPrimaryStatus) & 0x08) // loop while IRQ pending
                                                // Attention: IRQ bit is
                                                // inverted when used with
                                                // low activ IRQ
      {
         irqMask = ReadIO(RegInterruptEn); // read enabled interrupts
         // read pending interrupts
         irqBits = ReadIO(RegInterruptRq) & irqMask;
         MpIsrInfo->irqSource |= irqBits; // save pending interrupts
         //************ LoAlertIRQ ******************
         if (irqBits & 0x01)    // LoAlert
         {
            nbytes = MFIFOLength - ReadIO(RegFIFOLength);
            // less bytes to send, than space in FIFO
            if ((MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent) <= nbytes)
            {
               nbytes = MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent;
               WriteIO(RegInterruptEn,0x01); // disable LoAlert IRQ
            }
            // write remaining data to the FIFO
            for ( cnt = 0;cnt < nbytes;cnt++)
            {
               WriteIO(RegFIFOData,MpIsrOut[MpIsrInfo->nBytesSent]);
               MpIsrInfo->nBytesSent++;
            }
            WriteIO(RegInterruptRq,0x01);  // reset IRQ bit
         }

         //************* TxIRQ Handling **************
         if (irqBits & 0x10)       // TxIRQ
         {
            WriteIO(RegInterruptRq,0x10);    // reset IRQ bit
            WriteIO(RegInterruptEn,0x82);    // enable HiAlert Irq for
                                           // response
            if (MpIsrInfo->cmd == PICC_ANTICOLL1) 	// if cmd is anticollision
	        {                                           // switch off parity generation
               WriteIO(RegChannelRedundancy,0x02);	// RXCRC and TXCRC disable, parity disable
	        }
         }

         //************* HiAlertIRQ or RxIRQ Handling ******************
         if (irqBits & 0x0E) // HiAlert, Idle or RxIRQ
         {
            // read some bytes ( length of FIFO queue)
            // into the receive buffer
            nbytes = ReadIO(RegFIFOLength);
            // read date from the FIFO and store them in the receive buffer
            for ( cnt = 0; cnt < nbytes; cnt++)
            {
               MpIsrIn[MpIsrInfo->nBytesReceived] = ReadIO(RegFIFOData);
               MpIsrInfo->nBytesReceived++;
            }
            WriteIO(RegInterruptRq,0x0A & irqBits);
                                       // reset IRQ bit - idle irq will
                                       // be deleted in a seperate section
         }

         //************** IdleIRQ Handling ***********
         if (irqBits & 0x04)     // Idle IRQ
         {
            WriteIO(RegInterruptEn,0x20); // disable Timer IRQ
            WriteIO(RegInterruptRq,0x20); // disable Timer IRQ request
            irqBits &= ~0x20;   // clear Timer IRQ in local var
            MpIsrInfo->irqSource &= ~0x20; // clear Timer IRQ in info var
                                        // when idle received, then cancel
                                        // timeout
            WriteIO(RegInterruptRq,0x04);  // reset IRQ bit
            // status should still be MI_OK
            // no error - only used for wake up
         }

         //************* TimerIRQ Handling ***********
         if (irqBits & 0x20)       // timer IRQ
         {
            WriteIO(RegInterruptRq,0x20); // reset IRQ bit
            MpIsrInfo->status = MI_NOTAGERR; // timeout error
                                             // otherwise ignore the interrupt
         }

      }
   }
#else
   static unsigned char  idata irqBits;
   static unsigned char  idata irqMask;            
   static unsigned char  idata oldPageSelect;
   static unsigned char  idata nbytes;
   static unsigned char  idata cnt;

   if (MpIsrInfo && MpIsrOut && MpIsrIn)  // transfer pointers have to be set
                                          // correctly
   {
      oldPageSelect = ReadRawIO(RegPage); // save old page select 
                                          // Attention: ReadIO cannnot be
                                          // used because of the internal
                                          // write sequence to the page 
                                          // reg
      WriteRawIO(RegPage,0x80);                   // select page 0 for ISR
      while( (ReadRawIO(RegPrimaryStatus) & 0x08)) // loop while IRQ pending
      {
         irqMask = ReadRawIO(RegInterruptEn); // read enabled interrupts
         // read pending interrupts
         irqBits = ReadRawIO(RegInterruptRq) & irqMask;
         MpIsrInfo->irqSource |= irqBits; // save pending interrupts
        
		 //************ LoAlertIRQ ******************
         if (irqBits & 0x01)    // LoAlert
         {  
            nbytes = MFIFOLength - ReadRawIO(RegFIFOLength);
            // less bytes to send, than space in FIFO
            if ((MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent) <= nbytes)
            {
               nbytes = MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent;
             WriteRawIO(RegInterruptEn,0x01); // disable LoAlert IRQ
            }																	   
            // write remaining data to the FIFO
            for ( cnt = 0;cnt < nbytes;cnt++)
            {
               WriteRawIO(RegFIFOData,MpIsrOut[MpIsrInfo->nBytesSent]);
               MpIsrInfo->nBytesSent++;
            }
            WriteRawIO(RegInterruptRq,0x01);  // reset IRQ bit
         }
      
        
		 //************* TxIRQ Handling **************
         if (irqBits & 0x10)       // TxIRQ
         {
            WriteRawIO(RegInterruptRq,0x10);    // reset IRQ bit 
            WriteRawIO(RegInterruptEn,0x82);    // enable HiAlert Irq for
                                                // response
            if (MpIsrInfo->cmd == PICC_ANTICOLL1) // if cmd is anticollision
            {                                     // switch off parity generation
               WriteIO(RegChannelRedundancy,0x02); // RxCRC and TxCRC disable, parity disable               
               WriteRawIO(RegPage,0x00);  // reset page address
            }
         }

        
		 //************* HiAlertIRQ or RxIRQ Handling ******************
         if (irqBits & 0x0E) // HiAlert, Idle or RxIRQ
         {
            // read some bytes ( length of FIFO queue)              
            // into the receive buffer
            nbytes = ReadRawIO(RegFIFOLength);
            // read date from the FIFO and store them in the receive buffer
            for ( cnt = 0; cnt < nbytes; cnt++)               
            {
               MpIsrIn[MpIsrInfo->nBytesReceived] = ReadRawIO(RegFIFOData);
               MpIsrInfo->nBytesReceived++;
            }
            WriteRawIO(RegInterruptRq,0x0A & irqBits);  
                                       // reset IRQ bit - idle irq will
                                       // be deleted in a seperate section
         }   
   
        
		 //************** IdleIRQ Handling ***********
         if (irqBits & 0x04)     // Idle IRQ
         {
            WriteRawIO(RegInterruptEn,0x20); // disable Timer IRQ
            WriteRawIO(RegInterruptRq,0x20); // disable Timer IRQ request
            irqBits &= ~0x20;   // clear Timer IRQ in local var
            MpIsrInfo->irqSource &= ~0x20; // clear Timer IRQ in info var
                                        // when idle received, then cancel
                                        // timeout
            WriteRawIO(RegInterruptRq,0x04);  // reset IRQ bit 
            // status should still be MI_OK
            // no error - only used for wake up
         }
       
         
		 //************* TimerIRQ Handling ***********
         if (irqBits & 0x20)       // timer IRQ	  the timeout  !!Hack
         {
            WriteRawIO(RegInterruptRq,0x20); // reset IRQ bit 
            MpIsrInfo->status = MI_NOTAGERR; // timeout error  what the timeout ,how long the time setting for IRQ?
                                             // otherwise ignore the interrupt
         }

         
      }
      WriteRawIO(RegPage,oldPageSelect | 0x80);
   }
#endif
}


/***************************************************************************************
****************************************************************************************
                                               										   *
代码段说明: 以下代码专用于Mifare Pro卡片的操作函数.									   *												   *
																					   *
代码核心函数: M500PiccExchangeBlock.												   *
																					   *
功能说明: 数据块交换数据.															   *
																					   *
													                                   *
****************************************************************************************																					   
****************************************************************************************/



char M500PiccCascSelect(unsigned char select_code, 
                        unsigned char *snr,
                        unsigned char *sak)
{
   char   status = MI_OK; 
   char   grid   = 0x0D;

   if ((status = M500PcdSetDefaultAttrib()) == MI_OK)
   {
      M500PcdSetTmo(2);
    
      WriteIO(RegChannelRedundancy,0x0F); // RxCRC,TxCRC, Parity enable
      ClearBitMask(RegControl,0x08);    // disable crypto 1 unit
   
      //************* Cmd Sequence ********************************** 
      ResetInfo(&MInfo);   
      SndBuffer[0] = select_code;
      SndBuffer[1] = 0x70;         // number of bytes send
      
      memcpy(SndBuffer + 2,snr,4);
      SndBuffer[6] = SndBuffer[2] 
                      ^ SndBuffer[3] 
                      ^ SndBuffer[4] 
                      ^ SndBuffer[5];
      MInfo.nBytesToSend   = 7;
//    MInfo.DisableDF = 1;
    
      status = M500PcdCmd(PCD_TRANSCEIVE,
                          SndBuffer,
                          RcvBuffer,
                          &MInfo);
      
	  ComWrite(&status,1);
	  ComWrite(&grid,1);
     
     
   
      *sak = 0;   
      if (status == MI_OK)    // no timeout occured
      {
         if (MInfo.nBitsReceived != 8)    // last byte is not complete
         {
            status = MI_BITCOUNTERR;
         }
         else
         {
            memcpy(MLastSelectedSnr,snr,4);            
         }
      }
      // copy received data in any case - for debugging reasons
      *sak = RcvBuffer[0];
   }
   return status;
}  




char M500PiccCascAnticoll (unsigned char select_code,
                           unsigned char bcnt,       
                           unsigned char *snr)       
{
   char idata status = MI_OK;
   char idata snr_in[4];     // copy of the input parameter snr
   char idata nbytes = 0;
   char idata nbits = 0;
   char idata complete = 0;
   char idata i        = 0;
   char idata byteOffset = 0;
   unsigned char idata snr_crc;
   unsigned char idata snr_check;
   unsigned char dummyShift1;       // dummy byte for snr shift
   unsigned char dummyShift2;       // dummy byte for snr shift 
   char          grid = 0x0E;  
 
   //************* Initialisation ******************************
  
   //M500PcdSetTmo(2);
   memcpy(snr_in,snr,4);   
   
   WriteIO(RegDecoderControl,0x28); // ZeroAfterColl aktivieren   
   ClearBitMask(RegControl,0x08);    // disable crypto 1 unit
      
   //************** Anticollision Loop ***************************

   complete = 0;
//   bcnt = 0;   // no part of the snr is known
   while (!complete && (status == MI_OK) )
   {
      ResetInfo(&MInfo);           
      WriteIO(RegChannelRedundancy,0x03); // RxCRC and TxCRC disable, parity enable
      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 inconsistancy in the anticollision sequence
         // (will be solved soon), the case of 7 bits has to be treated in a
         // separate way - please note the errata sheet
         if (nbits == 7)
         {
            MInfo.cmd = PICC_ANTICOLL1;   // pass command flag to ISR        
            WriteIO(RegBitFraming,nbits); // reset RxAlign to zero
         }
      } 
      else
      {
         nbytes = bcnt / 8;
      }

      SndBuffer[0] = select_code;
      SndBuffer[1] = 0x20 + ((bcnt/8) << 4) + nbits; //number of bytes send
               
      for (i = 0; i < nbytes; i++)  // Sende Buffer beschreiben
      {
         SndBuffer[i + 2] = snr_in[i];
      }
      MInfo.nBytesToSend   = 2 + nbytes;
	     
 	  M500PcdSetTmo(2);
      status = M500PcdCmd(PCD_TRANSCEIVE,
                          SndBuffer,
                          RcvBuffer,
                          &MInfo);
   	  
	  ComWrite(&status,1);
	  ComWrite(&grid,1);
    
      // in order to solve an inconsistancy in the anticollision sequence
      // (will 

⌨️ 快捷键说明

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