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

📄 pcdutils.c

📁 菲利普RC500源代码,使用单片机89c52作微处理器,采用c语言进行编程.
💻 C
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////
//       W R I T E   A   P C D   C O M M A N D 
///////////////////////////////////////////////////////////////////////
char  PcdSingleResponseCmd(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;

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

   FlushFIFO();            // flush FIFO buffer

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

   // initialising the ISR-Function pointer for mifare
   // protocol - do this after initialising the MpXXXX variables
   PcdIsrFct = SingleResponseIsr; 
                         
   info->irqSource = 0x0; // reset interrupt flags

   READER_INT_ENABLE;

   // 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 = -(ReadRC(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 = -(ReadRC(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 

      GT_vInitTmr(TIMER_3,0x87);          // initialise and start
      GT_vLoadTmr(TIMER_3,0xF00);        // guard timer for reader 

      GT_vInitTmr(TIMER_4,0x04);          // initialise and start
      GT_vLoadTmr(TIMER_4,0x01);        // processing time counter
                                        // 6.4 us resolution - max 420 ms 

      LED_ON;                                        
      WriteRC(RegInterruptEn,irqEn | 0x80);  //necessary interrupts are enabled // count up from 1
      
      GT_vStartTmr(TIMER_3);            // start timer 3
      GT_vStartTmr(TIMER_4);            // start timer 4

      WriteRC(RegCommand,cmd);               //start command   

      // 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

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

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

      T3IR = 0;
      WriteRC(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 = (ReadRC(RegErrorFlag) & 0x17))) // error occured
         {
            if (tmpStatus & 0x01)   // collision detected
            {
               info->collPos = ReadRC(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 (cmd == PCD_TRANSCEIVE || cmd == PCD_RECEIVE)
         {
            // number of bits in the last byte
            lastBits = ReadRC(RegSecondaryStatus) & 0x07;
            if (lastBits)
               info->nBitsReceived += (info->nBytesReceived-1) * 8 + lastBits;
            else
               info->nBitsReceived += info->nBytesReceived * 8;
         }
      }
      else
      {
         info->collPos = 0x00;
      }
   }

   READER_INT_DISABLE;

   PcdIsrFct = EmptyPcdIsrFct; // reset the ISR-Function pointer to
                               // an empty function body
                               // do this before clearing the Mp XXXX variables

   MpIsrInfo = 0;         // reset interface variables for ISR
   MpIsrOut  = 0;
   MpIsrIn   = 0; 
   return status;
}   

⌨️ 快捷键说明

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