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

📄 mfrc500.c

📁 mifarea卡程序mifarea卡程序mifarea卡程序
💻 C
📖 第 1 页 / 共 5 页
字号:
//#include <reg51rx2.h>
#include <reg52.h>
#include <intrins.h>
#include "string.h"
#include "stimer.h"
#include "ucio.h"
#include "mfrc500.h"
#include "uart.h"
#include "v51rx2.h"
#include "intrsc.h"
#include "MifarePro.h"
#include "global.h"


#define DEBUGRC500

#define enableme()  EX0 = 1
#define disableme() EX0 = 0

//static volatile bit  fSameCard;

static   volatile MfCmdInfo     MInfo;

// Variable in order to exchange data between function and ISR
static   volatile MfCmdInfo     *MpIsrInfo = 0;
        // ISR send buffer
static   volatile unsigned char *MpIsrOut  = 0;
         // ISR receive buffer
static   volatile unsigned char *MpIsrIn   = 0;

static unsigned char RxGain = 0x71;//73:42db, 72:38, 71:30, 70:27///////////////////

#define MFIFOLength 64

uchar xdata SndBuffer[64];
uchar xdata RcvBuffer[64];


// storage of the last selected serial number including check byte.
// For multi level serial numbers, only the first 4 bytes are stored.
unsigned char MLastSelectedSnr[5];


void ResetInfo(MfCmdInfo *info)
{
    info->cmd= 0;
    info->status = MI_OK;
    info->irqSource= 0;
    info->nBytesToSend = 0;
    info->nBytesSent = 0;
    info->nBytesReceived = 0;
    info->nBitsReceived  = 0;
    info->collPos  = 0;
}

void SetBitMask(uchar reg,uchar mask)
{
    uchar data tmp = 0x0;
    tmp = ReadIO(reg);
    WriteIO(reg,tmp | mask);
}

void ClearBitMask(uchar reg,uchar mask)
{
    uchar tmp = 0x0;
    tmp = ReadIO(reg);
    WriteIO(reg,tmp & ~mask);
}

// clear fifo
void FlushFIFO(void)
{
    SetBitMask(RegControl,0x01);
}

/************************************
 * set timeout length               *
 * tmolength: timeout length        *
 ************************************/
 /*
void M500PcdSetTmo(uchar tmoLength)
{
    switch(tmoLength)
    {
        case 1:
            WriteIO(RegTimerClock,0x07);
            WriteIO(RegTimerReload,0x6a);
            break;
        case 2:
            WriteIO(RegTimerClock,0x07);
            WriteIO(RegTimerReload,0xa0);
            break;
        case 3:
            WriteIO(RegTimerClock,0x09);
            WriteIO(RegTimerReload,0xa0);
            break;
        case 4:
            WriteIO(RegTimerClock,0x09);
            WriteIO(RegTimerReload,0xff);
            break;
        case 5:
            WriteIO(RegTimerClock,0x0b);
            WriteIO(RegTimerReload,0xff);
            break;
        case 6:
            WriteIO(RegTimerClock,0x0d);
            WriteIO(RegTimerReload,0xff);
            break;
        case 7:
            WriteIO(RegTimerClock,0x0f);
            WriteIO(RegTimerReload,0xff);
            break;
        default:
            WriteIO(RegTimerClock,0x07);
            WriteIO(RegTimerReload,tmoLength);
            break;
    }
} */

void M500PcdSetTmo(unsigned char tmoLength)
{
   switch(tmoLength)
   {  // timer clock frequency 13,56 MHz
      case 1:                       // short timeout (1,0 ms)
         WriteIO(RegTimerClock,0x07); // TAutoRestart=0,TPrescale=128
         WriteIO(RegTimerReload,0x6a);// TReloadVal = 'h6a =106(dec) 
         break;
      case 2:                       // medium timeout (1,5 ms)
         WriteIO(RegTimerClock,0x07); // TAutoRestart=0,TPrescale=128
         WriteIO(RegTimerReload,0xa0);// TReloadVal = 'ha0 =160(dec) 
         break;
      case 3:                       // medium timeout (6 ms)
         WriteIO(RegTimerClock,0x09); // TAutoRestart=0,TPrescale=4*128
         WriteIO(RegTimerReload,0xa0);// TReloadVal = 'ha0 =160(dec) 
         break;
      case 4:                       // long timeout (9.6 ms)
         WriteIO(RegTimerClock,0x09); // TAutoRestart=0,TPrescale=4*128
         WriteIO(RegTimerReload,0xff);// TReloadVal = 'hff =255(dec) 
         break;
      case 5:                       // long timeout (38.5 ms)
         WriteIO(RegTimerClock,0x0b); // TAutoRestart=0,TPrescale=16*128
         WriteIO(RegTimerReload,0xff);// TReloadVal = 'hff =255(dec) 
         break;
      case 6:                       // long timeout (154 ms)
         WriteIO(RegTimerClock,0x0d); // TAutoRestart=0,TPrescale=64*128
         WriteIO(RegTimerReload,0xff);// TReloadVal = 'hff =255(dec) 
         break;
      case 7:                       // long timeout (616.2 ms)
         WriteIO(RegTimerClock,0x0f); // TAutoRestart=0,TPrescale=256*128
         WriteIO(RegTimerReload,0xff);// TReloadVal = 'hff =255(dec) 
         break;
      case 8:
	     WriteIO(RegTimerClock,0x0f);
		 WriteIO(RegTimerReload,0xB6);   //e1  
		 break;
      case 9:
	     WriteIO(RegTimerClock,0x11);
		 WriteIO(RegTimerReload,0xff);
	  case 10:
	     WriteIO(RegTimerClock,0x12);
		 WriteIO(RegTimerReload,0xff);
		 break;
	  case 11:
	     WriteIO(RegTimerClock,0x13);
		 WriteIO(RegTimerReload,0xff);
		 break;
	  case 12:
	     WriteIO(RegTimerClock,0x14);
		 WriteIO(RegTimerReload,0xff);
		 break;
	  case 13:
	     WriteIO(RegTimerClock,0x10);
		 WriteIO(RegTimerReload,0xE1);
		 break;
	  case 14:
	     WriteIO(RegTimerClock,0x0F);
		 WriteIO(RegTimerReload,0xB0);	 //E1
		 break;
	  case 15:
	     WriteIO(RegTimerClock,0x0F);
		 WriteIO(RegTimerReload,0xB1);		 //Process the cmmand .setting the time in the MFRC500 timer.
		 break;
	  case 16:
	     WriteIO(RegTimerClock,0x0C);
		 WriteIO(RegTimerReload,0xFF);
		 break;
	  default:                              // 
         WriteIO(RegTimerClock,0x07);       // TAutoRestart=0,TPrescale=128
         WriteIO(RegTimerReload,tmoLength); // TReloadVal = 'h6a =tmoLength(dec) 
         break;
   }     
}


/****************************
 * excute mfrc500 command   *
 ****************************/
#if 1
uchar M500PcdCmd(unsigned char cmdcode, unsigned char* send, unsigned char* rcv, MfCmdInfo *info)
{
    uchar  data tmpStatus;
    uchar  data lastBits;
    uchar  data status    = MI_OK;
    uchar  data irqEn     = 0x00;
    uchar  data waitFor   = 0x00;
    uint   data starttime;
	uchar  data i;

    WriteIO(RegInterruptEn,0x7F);   // disable all interrupts
    WriteIO(RegInterruptRq,0x7F);   // reset interrupt requests
    WriteIO(RegCommand,PCD_IDLE);   // terminate probably running command

    FlushFIFO();                    // flush FIFO buffer

    // save info structures to module pointers
    MpIsrInfo = info;
    MpIsrOut  = send;
    MpIsrIn   = rcv;

    info->irqSource = 0x0; // reset interrupt flags
    
    enableme();		    

    // depending on the command code, appropriate interrupts are enabled (irqEn)
    // and the commit interrupt is choosen (waitFor).
    switch(cmdcode)
    {
        case PCD_IDLE:                   // nothing else required
            irqEn = 0x00;
            waitFor = 0x00;
            break;

        case PCD_WRITEE2:                // LoAlert and TxIRq
            irqEn = 0x11;
            waitFor = 0x10;
            break;

        case PCD_READE2:                 // HiAlert, LoAlert and IdleIRq
            irqEn = 0x07;
            waitFor = 0x04;
            break;

        case PCD_LOADCONFIG:             // IdleIRq and LoAlert 
        case PCD_LOADKEYE2:              // IdleIRq and LoAlert 
        case PCD_AUTHENT1:               // IdleIRq and LoAlert 
            irqEn = 0x05;
            waitFor = 0x04;
            break;

        case PCD_CALCCRC:                // LoAlert and TxIRq
            irqEn = 0x11;
            waitFor = 0x10;
            break;

        case PCD_AUTHENT2:               // IdleIRq
            irqEn = 0x04;
            waitFor = 0x04;
            break;

        case PCD_RECEIVE:                // HiAlert and IdleIRq
            info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4);      ////////////////
            irqEn = 0x06;
            waitFor = 0x04;
            break;

        case PCD_LOADKEY:                // IdleIRq
            irqEn = 0x05;
            waitFor = 0x04;
            break;

        case PCD_TRANSMIT:               // LoAlert and IdleIRq
            irqEn = 0x05;
            waitFor = 0x04;
            break;

        case PCD_TRANSCEIVE:             // TxIrq, RxIrq, IdleIRq and LoAlert
            info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4); //////////////
            irqEn = 0x3D;   //0x1D;
            waitFor = 0x04;
            break;

        default:
            status = MI_UNKNOWN_COMMAND;
		  	break;
    }

    if (status == MI_OK)
    {
        irqEn |= 0x20;
        waitFor |= 0x20;

		for(i=0;i<253;i++)
		{
		 _nop_();
		}

        WriteIO(RegInterruptEn,irqEn | 0x80);   // enable interrupt

        WriteIO(RegCommand,cmdcode);            // send command
        starttime = GetTickCount();	     

        while (!((MpIsrInfo->irqSource & waitFor)
               || (GetTickCount() - starttime > 420)));   // wait for cmd completion or timeout
	   
	   //while(!MpIsrInfo->irqSource & waitFor);
               
        // disableme();    // disable interrupt just when cmd complete, 050517

        WriteIO(RegInterruptEn,0x7F);          // disable all interrupts
        WriteIO(RegInterruptRq,0x7F);          // clear all interrupt requests
        SetBitMask(RegControl,0x04);           // stop timer now
        WriteIO(RegCommand,PCD_IDLE);          // reset command register

        if (!(MpIsrInfo->irqSource & waitFor))   // reader has not terminated   This logic has a problem about the timeout!!
        {                                        // timer 3 expired
            status = MI_ACCESSTIMEOUT;			 // This code do not support the MiarePro. freqence timeout!!!
        }
        else
            status = MpIsrInfo->status;           // set status	 The real timeout occured ,then will the NO_TAGERR!

        if (status == MI_OK)                     // no timeout error occured
        {
           if (tmpStatus = (ReadIO(RegErrorFlag) & 0x17/*0x1f*/)) // error occured
           {
              if (tmpStatus & 0x01)   // collision detected
              {
                 info->collPos = ReadIO(RegCollpos); // read collision position
                 status = MI_COLLERR;
              }
              else
              {
                 info->collPos = 0;
                 if (tmpStatus & 0x02)   // parity error
                 {
                    status = MI_PARITYERR;
                 }
              }
              
              if (tmpStatus & 0x04)   // framing error
              {
                 status = MI_FRAMINGERR;
              }
              if (tmpStatus & 0x10)   // FIFO overflow
              {
                 FlushFIFO();
                 status = MI_OVFLERR;
              }
     	      if (tmpStatus & 0x08) //CRC error
    	      {
                 status = MI_CRCERR;
    	      }
              if (status == MI_OK)
                 status = MI_NY_IMPLEMENTED;
              // key error occures always, because of
              // missing crypto 1 keys loaded
           }
           // if the last command was TRANSCEIVE, the number of
           // received bits must be calculated - even if an error occured
           if (cmdcode == PCD_TRANSCEIVE || cmdcode == PCD_RECEIVE) ////////////////////
           {
              // number of bits in the last byte
              lastBits = ReadIO(RegSecondaryStatus) & 0x07;
              if (lastBits)
                 info->nBitsReceived += (info->nBytesReceived-1) * 8 + lastBits;
              else
                 info->nBitsReceived += info->nBytesReceived * 8;
           }
        }
        else
        {
           info->collPos = 0x00;
        }
    }
    disableme();
    
    MpIsrInfo = 0;         // reset interface variables for ISR
    MpIsrOut  = 0;
    MpIsrIn   = 0;
    return status;
}
#else
//////////////////////////////////////////////////////////////////////
//       W R I T E   A   P C D   C O M M A N D 
///////////////////////////////////////////////////////////////////////
char  M500PcdCmd(unsigned char cmd,
               volatile unsigned char* send, 
               volatile unsigned char* rcv,
               volatile MfCmdInfo *info)
{     
   char          status    = MI_OK;
   char          tmpStatus ;
   unsigned char lastBits;

   unsigned char irqEn     = 0x00;
   unsigned char waitFor   = 0x00;
   unsigned char timerCtl  = 0x00;

   WriteIO(RegInterruptEn,0x7F); // disable all interrupts
   WriteIO(RegInterruptRq,0x7F); // reset interrupt requests
   WriteIO(RegCommand,PCD_IDLE); // terminate probably running command

   FlushFIFO();            // flush FIFO buffer

   // save info structures to module pointers
   MpIsrInfo = info;  
   MpIsrOut  = send;
   MpIsrIn   = rcv;

   info->irqSource = 0x0; // reset interrupt flags

   enableme();

   // depending on the command code, appropriate interrupts are enabled (irqEn)
   // and the commit interrupt is choosen (waitFor).
   switch(cmd)
   {
      case PCD_IDLE:                   // nothing else required
         irqEn = 0x00;
         waitFor = 0x00;
         break;
      case PCD_WRITEE2:                // LoAlert and TxIRq
         irqEn = 0x11;
         waitFor = 0x10;
         break;
      case PCD_READE2:                 // HiAlert, LoAlert and IdleIRq
         irqEn = 0x07;
         waitFor = 0x04;
         break;
      case PCD_LOADCONFIG:             // IdleIRq and LoAlert
      case PCD_LOADKEYE2:              // IdleIRq and LoAlert
      case PCD_AUTHENT1:               // IdleIRq and LoAlert
         irqEn = 0x05;
         waitFor = 0x04;

⌨️ 快捷键说明

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