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

📄 armspi.c

📁 用ARM的LPC2200来 SPI通信方式下读卡器驱动程序 其读卡器为FM172
💻 C
📖 第 1 页 / 共 4 页
字号:
}

//////////////////////////////////////////////////////////////////////
//       W R I T E   A   P C D   C O M M A N D 
///////////////////////////////////////////////////////////////////////
int8  FM1702PcdCmd(uint8 cmd,volatile uint8* send, volatile uint8* rcv, volatile MfCmdInfo *info)
{     
   int8           status    = MI_OK;
   int8           tmpStatus ;
   uint8  lastBits;

   uint8  irqEn     = 0x00;
   uint8  waitFor   = 0x00;
   
   WriteIO(RegInterruptEn,0x7F); 
   WriteIO(RegInterruptRq,0x7F); 
   WriteIO(RegCommand,PCD_IDLE); 

   FlushFIFO();            // 清空FIFO

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

   info->irqSource = 0x0; // reset interrupt flags
  
   switch(cmd)
   {
      case PCD_IDLE:                   // 空闲命令不用打开任何中断
         irqEn = 0x00;
         waitFor = 0x00;
         break;
      case PCD_WRITEE2:                // 写E2PROM命令
         irqEn = 0x11;
         waitFor = 0x10;
         break;
      case PCD_READE2:                 // 读E2PROM
         irqEn = 0x07;
         waitFor = 0x04;
         break;
      case PCD_LOADCONFIG:             // 配置命令
      case PCD_LOADKEYE2:              // 装载密钥须打开
      case PCD_AUTHENT1:               // 验证1须打开
         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 |= 0xA0;                       
      waitFor |= 0x20;                      // always wait for timeout 
     start_timeout(8000);          // initialise and start guard timer for reader
      				    // 50us resolution, 200ms
       VICIntEnClr=(1<<14);				  
      WriteIO(RegInterruptEn,irqEn); 
       VICIntEnable=(1<<14);
      WriteIO(RegCommand,cmd);               //写命令,
      // wait for commmand completion
      // a command is completed, if the corresponding interrupt occurs
      // or a timeout is signaled  
      while (!((MpIsrInfo->irqSource & waitFor)|| Timer1out_flag)); 
             // wait for cmd completion or timeou
      WriteIO(RegInterruptEn,0x7F);         
      WriteIO(RegInterruptRq,0x7F);         
      SetBitMask(RegControl,0x04);          

      stop_timeout();  			// stop timeout for reader
      WriteIO(RegCommand,PCD_IDLE);        
      if (!(MpIsrInfo->irqSource & waitFor))   // reader has not terminated
      {           // timer 2 expired
         status = MI_ACCESSTIMEOUT;
      }
      else
         status = MpIsrInfo->status;           // set status

      if (status == MI_OK)    //no timeout error occured
      {  tmpStatus = (ReadIO(RegErrorFlag) & 0x17);
         if (tmpStatus) // 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();	 //清空	FIFO缓冲区
               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 (cmd == PCD_TRANSCEIVE)
         {
            // 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;
      }
   }
   MpIsrInfo = 0;         // reset interface variables for ISR
   MpIsrOut  = 0;
   MpIsrIn   = 0; 
   return status;
}   

//////////////////////////////////////////////////////////////////////
//   S E T   A   B I T   M A S K 
///////////////////////////////////////////////////////////////////////
int8 SetBitMask(uint8 reg,uint8 mask) // 
{
   int8  tmp = 0x0;

   tmp = ReadIO(reg);
   WriteIO(reg,tmp | mask);  // set bit mask
   return 0x0;
}

//////////////////////////////////////////////////////////////////////
//   C L E A R   A   B I T   M A S K 
///////////////////////////////////////////////////////////////////////
int8 ClearBitMask(uint8 reg,uint8 mask) // 
{
   int8  tmp = 0x0;

   tmp = ReadIO(reg);
   WriteIO(reg,tmp & ~mask);  // clear bit mask
   return 0x0;
}

///////////////////////////////////////////////////////////////////////
//                  F L U S H    F I F O
///////////////////////////////////////////////////////////////////////
void FlushFIFO(void)
{  
   SetBitMask(RegControl,0x01);//将Control寄存器中的FIFOFlush位置1
}

/*---------------------------------------------------------------------
//      M I F A R E   M O D U L E   R E S E T 
---------------------------------------------------------------------*/
int8 FM1702PcdReset(void)
{
   uint8 a;
   int8  status = MI_OK;
   IO0CLR=FM1702_RESET;    // clear reset pin--P0.11
   //delay_50us(500);  // wait for 25ms  
   OSTimeDly(OS_TICKS_PER_SEC/40); 
   IO0SET = FM1702_RESET;   // reset RC500
   //delay_50us(50);  // wait for 2.5ms
   OSTimeDly(OS_TICKS_PER_SEC/400);
   IO0CLR=FM1702_RESET;  // clear reset pin

   start_timeout(42000); 	// count down with a period of 50 us
   			        // 42000 * 50 us = 2.1 s
   
  // wait until reset command recognized
    a=(ReadIO(RegCommand) & 0x3F);
   while ((a != 0x3F) && !Timer1out_flag)   a=(ReadIO(RegCommand) & 0x3F);//退出---Timer1out_flag=1或Cmd=3F
   // while reset sequence in progress
   a=(ReadIO(RegCommand) & 0x3F);
   while (a && !Timer1out_flag) a=(ReadIO(RegCommand) & 0x3F); 
   stop_timeout();  		// stop timeout counter

   if (Timer1out_flag) 		
   {
      status = MI_RESETERR; 
      Timer1out_flag   = 0;	
   }
   else
   {
      WriteIO(RegPage,0x80); 
      if (ReadIO(RegCommand)!= 0x00)
      {                           
          status = MI_INTERFACEERR;
      }
      else
         status=MI_OK;
      WriteIO(RegPage,0x00); 
      				
   }
   return status;
}

///////////////////////////////////////////////////////////////////////
//      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
///////////////////////////////////////////////////////////////////////
int8 FM1702PcdConfig(void)
{
   int8  status;

   if ((status = FM1702PcdReset()) == MI_OK)
   {
     // test clock Q calibration - value in the range of 0x46 expected
     WriteIO(RegClockQControl,0x0);
     WriteIO(RegClockQControl,0x40);
     delay_50us(2);  // wait approximately 100 us - calibration in progress等待约100us
     //OSTimeDly(1);
     ClearBitMask(RegClockQControl,0x40); // clear bit ClkQCalib for further calibration
                                                 
                                          
     WriteIO(RegBitPhase,0xAD);      

     // initialize minlevel
     WriteIO(RegRxThreshold,0xFF);   
  
     // disable auto power down
     WriteIO(RegRxControl2,0x01);
     WriteIO(RegFIFOLevel,0x04);   
     
     //Timer configuration
     WriteIO(RegTimerControl,0x02);  // TStopRxEnd=0,TStopRxBeg=0,TStartTxEnd=1,TStartTxBeg=0
                // timer must be stopped manually

     FM1702PcdSetTmo(1);               // short timeout

     WriteIO(RegIRqPinConfig,0x03); 

     FM1702PcdRfReset(1);            // Rf - reset and enable output driverRF复位50us   
    }
  
   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
///////////////////////////////////////////////////////////////////////
int8 FM1702PcdMfInOutMasterConfig(void)
{
   WriteIO(RegRxControl2,0x42);
   WriteIO(RegTxControl,0x10);
   WriteIO(RegBitPhase,0x11);
   return MI_OK;
}     


///////////////////////////////////////////////////////////////////////
//          M I F A R E    R E Q U E S T 
///////////////////////////////////////////////////////////////////////
int8 FM1702PiccRequest(uint8 req_code, uint8 *atq) 
// req_code ALL = 0x52 or IDLE = 0x26;atq:answer to request
{
   int8  status = MI_OK;
    //************* initialize ******************************
   WriteIO(RegChannelRedundancy,0x03); 
   ClearBitMask(RegControl,0x08);    
   WriteIO(RegBitFraming,0x07);        
   SetBitMask(RegTxControl,0x03);   
   
   ResetInfo(MInfo);   
   MSndBuffer[0] = req_code;
   MInfo.nBytesToSend   = 1;   
   status = FM1702PcdCmd(PCD_TRANSCEIVE,MSndBuffer,MRcvBuffer, &MInfo);  
   if (status)      // error occured
   {
      *atq = 0;
   } 
   else 	
   {
      if (MInfo.nBitsReceived != 16) // 2 bytes expected
      {
         *atq = 0;
         status = MI_BITCOUNTERR;	
      } 
      else 	
      {
         status = MI_OK;
         memcpy1(atq,(uint8*)MRcvBuffer,2);
      }
   }
   return status; 
}

///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
int8 FM1702PiccAnticoll (uint8 bcnt, uint8 *snr)
{

   int8  status = MI_OK;
   uint8  snr_in[4];     // copy of the input parameter snr
   uint8 _0000[5]="0000";
   int8  nbytes = 0;
   int8  nbits = 0;

⌨️ 快捷键说明

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