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

📄 mfrc500uc.c

📁 MF500芯片的RFID读卡器程序
💻 C
📖 第 1 页 / 共 3 页
字号:
*              - PCD_AUTHENT2
*              - PCD_RECEIVE
*              - PCD_LOADKEY
*              - PCD_TRANSMIT
*              - PCD_TRANSCEIVE
*             
*       send  (IN)
*             byte stream of variable length, which should be send to
*             the PICC, the length of stream has to be specified
*             in the info - structure
*       rcv   (OUT) 
*             byte stream of variable length, which was received 
*             from the PICC. The length can be obtained from the
*             info - structure
*       info  (OUT)
*             communication and status structure
* return: enum:
*          - MI_OK               operation without error
*          - MI_NOTAGERR         no tag in rf field
*          - MI_ACCESSTIMEOUT    RIC is not responding in time
*          - MI_COLLERR          collision in during rf data transfer
*          - MI_PARITYERR        parity error while receiving data
*          - MI_FRAMINGERR       framing error - start bit not valid
*          - MI_OVFLERR          FIFO overflow - to many data bytes
*          - MI_CRCERR           CRC error of received data
*          - MI_NY_IMPLEMENTED   internal error - source not identified
*         
*
* This function provides the central interface to the reader module.
* Depending on the "cmd"-value, all necessary interrupts are enabled
* and the communication is started. While the processing is done by
* the reader module, this function waits for its completion.
*
* It's notable, that the data in the send byte stream is written 
* to the FIFO of the reader module by the ISR itself. Immediate after 
* enabling the interrupts, the LoAlert interrupt is activated.
*
* The ISR writes the data to the FIFO. This function is not directly involved
* in writing or fetching data from FIFO, all work is done by the 
* corresponding ISR.After command completion, the error status is evaluated and 
* returned to the calling function.
*/ 
char PcdSingleResponseCmd(unsigned char cmd,
                volatile unsigned char* send, 
                volatile unsigned char* rcv,
                volatile MfCmdInfo *info);

/// Basic Register definitions
/*!
* return: none
*/
char PcdBasicRegisterConfiguration(void);

/// Set Reader IC Register Bit
/*!
* -o  reg  (IN)
*             register address
* -o  mask (IN)
*             Bit mask to set
* return:     none
*              
* This function performs a read - modify - write sequence
* on the specified register. All bits with a 1 in the mask
* are set - all other bits keep their original value.
*/
void SetBitMask(unsigned char reg,unsigned char mask);

/// Clear Reader IC Register Bit
/*!
* -o  reg  (IN)
*             register address
* -o  mask (IN)
*             Bit mask to clear
* return: none
*              
* This function performs a read - modify - write sequence
* on the specified register. All bits with a 1 in the mask
* are cleared - all other bits keep their original value.
*/
void ClearBitMask(unsigned char reg,unsigned char mask);

/// Flush remaining data from the FIFO
/*!
* -o  none
* return: none
*              
* This function erases  all remaining data in the MF RC 500's FIFO .
* Before writing new data or starting a new command, all remaining data 
* from former  commands should be deleted.
*/
void FlushFIFO(void);

/// Sleep several milliseconds
/*
The implementation of this function depends heavily
on the microcontroller in use. The measurement need not to be
very accurate. Only make sure, that the periode is not shorter, than
the required one.
*/
void SleepMs(unsigned short ms);

/// Sleep several microseconds
/*
The implementation of this function depends heavily
on the microcontroller in use. The measurement need not to be
very accurate. Only make sure, that the periode is not shorter, than
the required one.
*/
void SleepUs(unsigned short us);


///////////////////////////////////////////////////////////////////////
//      M I F A R E   M O D U L E   C O N F I G U R A T I O N
///////////////////////////////////////////////////////////////////////
char Mf500PcdConfig(void)
{
   char status = MI_RESETERR;
      
   status = PcdReset();

   if (status == MI_OK)
   {
     if ((status = PcdBasicRegisterConfiguration()) == MI_OK);
     {
        Mf500PcdWriteAttrib(); // write current modulation parameters
        PcdRfReset(1); // Rf - reset and enable output driver    
     }
   }
   return status;
}

///////////////////////////////////////////////////////////////////////
//          M I F A R E   R E M O T E   A N T E N N A
//  Configuration of slave module
///////////////////////////////////////////////////////////////////////
char Mf500ActiveAntennaSlaveConfig(void)
{
   char status = MI_OK;

   FlushFIFO();    // empty FIFO
   ResetInfo(MInfo);   
   MSndBuffer[0] = 0x10; // addr low byte
   MSndBuffer[1] = 0x00; // addr high byte

   MSndBuffer[2] = 0x00; // Page
   MSndBuffer[3] = 0x7B; // RegTxControl modsource 11,InvTx2,Tx2RFEn,TX1RFEn
   MSndBuffer[4] = 0x3F; // RegCwConductance
   MSndBuffer[5] = 0x3F; // RFU13
   MSndBuffer[6] = 0x19; // RFU14
   MSndBuffer[7] = 0x13; // RegModWidth     
   MSndBuffer[8] = 0x00; // RFU16
   MSndBuffer[9] = 0x00; // RFU17
 
   MSndBuffer[10] = 0x00; // Page
   MSndBuffer[11] = 0x73; // RegRxControl1 
   MSndBuffer[12] = 0x08; // RegDecoderControl
   MSndBuffer[13] = 0x6c; // RegBitPhase     
   MSndBuffer[14] = 0xFF; // RegRxThreshold  
   MSndBuffer[15] = 0x00; // RegBPSKDemControl
   MSndBuffer[16] = 0x00; // RegRxControl2   
   MSndBuffer[17] = 0x00; // RegClockQControl

   MSndBuffer[18] = 0x00; // Page
   MSndBuffer[19] = 0x06; // RegRxWait
   MSndBuffer[20] = 0x03; // RegChannelRedundancy
   MSndBuffer[21] = 0x63; // RegCRCPresetLSB    
   MSndBuffer[22] = 0x63; // RegCRCPresetMSB    
   MSndBuffer[23] = 0x0;  // RFU25
   MSndBuffer[24] = 0x04; // RegMfOutSelect enable mfout = manchester HT
   MSndBuffer[25] = 0x00; // RFU27
     
   // PAGE 5      FIFO, Timer and IRQ-Pin Configuration
   MSndBuffer[26] = 0x00; // Page
   MSndBuffer[27] = 0x08; // RegFIFOLevel       
   MSndBuffer[28] = 0x07; // RegTimerClock      
   MSndBuffer[29] = 0x06; // RegTimerControl    
   MSndBuffer[30] = 0x0A; // RegTimerReload     
   MSndBuffer[31] = 0x02; // RegIRqPinConfig    
   MSndBuffer[32] = 0x00; // RFU    
   MSndBuffer[33] = 0x00; // RFU
   MInfo.nBytesToSend   = 34;
         
   status = PcdSingleResponseCmd(PCD_WRITEE2,
                   MSndBuffer,
                   MRcvBuffer,
                   &MInfo); // write e2
   return status;
}

///////////////////////////////////////////////////////////////////////
//          M I F A R E   R E M O T E   A N T E N N A
//  Configuration of master module
///////////////////////////////////////////////////////////////////////
char Mf500ActiveAntennaMasterConfig(void)
{
   char status = MI_OK;

   WriteRC(RegRxControl2,0x42);
   WriteRC(RegTxControl,0x10);
   WriteRC(RegBitPhase,0x11);
   WriteRC(RegMfOutSelect,0x02);

   return status;
}     
                  
///////////////////////////////////////////////////////////////////////
//          M I F A R E    R E Q U E S T 
///////////////////////////////////////////////////////////////////////
char Mf500PiccRequest(unsigned char req_code, // request code ALL = 0x52 
                                           // or IDLE = 0x26 
                   unsigned char *atq)     // answer to request
{
  return Mf500PiccCommonRequest(req_code,atq);
}

///////////////////////////////////////////////////////////////////////
//          M I F A R E   C O M M O N   R E Q U E S T 
///////////////////////////////////////////////////////////////////////
char Mf500PiccCommonRequest(unsigned char req_code, 
                            unsigned char *atq)
{
   char status = MI_OK;

    //************* initialize ******************************
   if ((status = Mf500PcdSetDefaultAttrib()) == MI_OK)
   {
   
      PcdSetTmo(60);
      
      WriteRC(RegChannelRedundancy,0x03); // RxCRC and TxCRC disable, parity enable
      ClearBitMask(RegControl,0x08);      // disable crypto 1 unit   
      WriteRC(RegBitFraming,0x07);        // set TxLastBits to 7 
      
      ResetInfo(MInfo);   
      MSndBuffer[0] = req_code;
      MInfo.nBytesToSend   = 1;   
      MInfo.DisableDF = 1;
      status = PcdSingleResponseCmd(PCD_TRANSCEIVE,
                         MSndBuffer,
                         MRcvBuffer,
                         &MInfo);
      if ((status == MI_OK) && (MInfo.nBitsReceived != 16)) // 2 bytes expected
      {
         status = MI_BITCOUNTERR;
      } 
      if ((status == MI_COLLERR) && (MInfo.nBitsReceived == 16)) //
         status = MI_OK; // all received tag-types are combined to the 16 bit
         
      // in any case, copy received data to output - for debugging reasons
      if (MInfo.nBytesReceived >= 2)
      {
         memcpy(atq,MRcvBuffer,2);      
      }
      else
      {
         if (MInfo.nBytesReceived == 1)
            atq[0] = MRcvBuffer[0];
         else
            atq[0] = 0x00;
         atq[1] = 0x00;
      }
   }
   return status; 
}

///////////////////////////////////////////////////////////////////////
//          M I F A R E    A N T I C O L L I S I O N
// for standard select
///////////////////////////////////////////////////////////////////////
char Mf500PiccAnticoll (unsigned char bcnt,
                     unsigned char *snr)
{
   return Mf500PiccCascAnticoll(0x93,bcnt,snr); // first cascade level
}

///////////////////////////////////////////////////////////////////////
//          M I F A R E    A N T I C O L L I S I O N
// for extended serial numbers
///////////////////////////////////////////////////////////////////////
char Mf500PiccCascAnticoll (unsigned char select_code,
                         unsigned char bcnt,       
                         unsigned char *snr)       
{
   char  status = MI_OK;
   char  snr_in[4];         // copy of the input parameter snr
   char  nbytes = 0;        // how many bytes received
   char  nbits = 0;         // how many bits received
   char  complete = 0;      // complete snr recived
   short i        = 0;
   char  byteOffset = 0;
   unsigned char snr_crc;   // check byte calculation
   unsigned char snr_check;
   unsigned char dummyShift1;       // dummy byte for snr shift
   unsigned char dummyShift2;       // dummy byte for snr shift   
 
   //************* Initialisierung ******************************
   if ((status = Mf500PcdSetDefaultAttrib()) == MI_OK)
   {
      PcdSetTmo(106);
      
      memcpy(snr_in,snr,4);   
      
      WriteRC(RegDecoderControl,0x28); // ZeroAfterColl aktivieren   
      ClearBitMask(RegControl,0x08);    // disable crypto 1 unit
         
      //************** Anticollision Loop ***************************
      complete=0;
      while (!complete && (status == MI_OK) )
      {
         // if there is a communication problem on the RF interface, bcnt 
         // could be larger than 32 - folowing loops will be defective.
         if (bcnt > 32)
         {
            status = MI_WRONG_PARAMETER_VALUE;
            continue;
         }
         ResetInfo(MInfo);
         MInfo.cmd = select_code;   // pass command flag to ISR        
         MInfo.DisableDF = 1;
         WriteRC(RegChannelRedundancy,0x03); // RxCRC and TxCRC disable, parity enable
         nbits = bcnt % 8;   // remaining number of bits
         if (nbits)
         {
            WriteRC(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
            if (nbits == 7 )
            {
            	MInfo.RxAlignWA = 1;
               MInfo.nBitsReceived = 7; // set flag for 7 bit anticoll, which is evaluated
                                        // in the ISRnBitsReceived        
               WriteRC(RegBitFraming,nbits); // reset RxAlign to zero
            }
         } 
         else
         {
            nbytes = bcnt / 8;
         }
  
         MSndBuffer[0] = select_code;
         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 = PcdSingleResponseCmd(PCD_TRANSCEIVE,
                            MSndBuffer,
                            MRcvBuffer,
                            &MInfo);

          // 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 
         if (MInfo.RxAlignWA)
         {
            // 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
         {

            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];
            }
            // 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;
            } 
            else 
            {
               if (status != MI_COLLERR ) // no error and no collision
               {
                  // 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;
               }
            }
        }
      }
   }
   // transfer snr_in to snr - even in case of an error - for 
   // debugging reasons

⌨️ 快捷键说明

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