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

📄 mfrc500.c.bak

📁 mifarea卡程序mifarea卡程序mifarea卡程序
💻 BAK
📖 第 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;
    }
}

/****************************
 * excute mfrc500 command   *
 ****************************/
#if 1
uchar M500PcdCmd(uchar cmdcode, uchar* send, uchar* 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;

    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;
        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
               
        // 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
        {                                        // timer 3 expired
            status = MI_ACCESSTIMEOUT;
        }
        else
            status = MpIsrInfo->status;           // set status

        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;
         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;
         waitFor = 0x04;
         break;
      default:
         status = MI_UNKNOWN_COMMAND;
   }        
   if (status == MI_OK)
   {
      // Initialize uC Timer for global Timeout management
      irqEn |= 0x20;                        // always enable timout irq
      waitFor |= 0x20;                      // always wait for timeout 
      WriteIO(RegInterruptEn,irqEn | 0x80);  //necessary interrupts are enabled // count up from 1
      
      WriteIO(RegCommand,cmd);               //start command   
      starttime = GetTickCount();

      // wait for commmand completion
      // a command is completed, if the corresponding interrupt occurs
      // or a timeout is signaled  

      while (!(MpIsrInfo->irqSource & waitFor
               || T3IR));                // wait for cmd completion or timeout

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

      GT_vStopTmr(TIMER_4);
      GT_vStopTmr(TIMER_3);
      LED_OFF;

      T3IR = 0;
      WriteIO(RegCommand,PCD_IDLE);          // reset command register

      if (!(MpIsrInfo->irqSource & waitFor))   // reader has not terminated
      {                                        // timer 3 expired
         status = MI_ACCESSTIMEOUT;
      }
      else
         status = MpIsrInfo->status;           // set status

      if (status == MI_OK)                     // no timeout error occured
      {
         if ((tmpStatus = (ReadIO(RegErrorFlag) & 0x17))) // 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

⌨️ 快捷键说明

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