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

📄 m500auc.c

📁 RFID的一些程序设计
💻 C
📖 第 1 页 / 共 5 页
字号:
	///////////////////////////////////////////////////////////////////////////////
	//    Copyright (c), Philips Semiconductors Gratkorn
	//
	//                  (C)PHILIPS Electronics N.V.2000
	//       All rights are reserved. Reproduction in whole or in part is 
	//      prohibited without the written consent of the copyright owner.
	//  Philips reserves the right to make changes without notice at any time.
	// Philips makes no warranty, expressed, implied or statutory, including but
	// not limited to any implied warranty of merchantibility or fitness for any
	//particular purpose, or that the use will not infringe any third party patent,
	// copyright or trademark. Philips must not be liable for any loss or damage
	//                          arising from its use.
	///////////////////////////////////////////////////////////////////////////////
	#define DLL_EXPORT      // library source module definition
	#include <p89c51rx.h>
	#include <Mfreg500.h>
	#include <M500A.h>
	#include <RdIo.h>
	#include <string.h>
	#include <stdio.h>
	#include <main.h>
	
	////////////////////////////////////////////////////////////////////////////////
	//                M O D U L E   D E F I N I T I O N
	////////////////////////////////////////////////////////////////////////////////
	// COMMENT: This library module is modified from the original source code for a
	//	    microcontroller C164 CI, to suit the general purpose 8051 mcu.
	//          The source can be ported to other platforms very easily. 
	//          The communication channel to the RC500 reader IC is assumed to be 
	//          unknown. All data is written with the generic IO functions 
	//          of the module ReaderIO.h. In our case the reader module is 
	//          connected via memory mapped io at base address 0x7f00.
	//          The interrupt pin of the reader IC is assumed to be connected to 
	//          the fast external interrupt pin INT0# (active low) and the reset
	//          pin of the reader IC should be connected to a dedicated port pin
	//          (Port3: Pin: 3).
	//          In this configuration, a reset of the reader module is independent
	//          from the reset of the microcontroller.
	//          In order to generate communication timeouts, 
	//          general purpose timer 2 of the microcontroller is used. This 
	//          timer need not to be initialised in advance. Before every usage 
	//          the timer is completely initialised in each function. 
	//          Non of the timers is essential for the functionality of the reader
	//          module, but are helpful furing software development. All protocoll 
	//          relevant timing constraints are generated
	//          by the internal timer of the reader module.
	//
	//          Some explanations to the programming method of this library.
	//          There are three kind of functions coded in this module.
	//            a) internal functions, which have no prototypes in a header
	//               file and are not intended to be used outside of this file
	//            b) commands, which are intended for the reader module itself
	//            c) commands, which are intended for any tag in the rf field.
	//               These commands are send to the reader and the reader module
	//               transmitts the data to the rf interface.
	//          Commands for the reader and for the tag have the appropriate 
	//          prefix (PCD for proximity coupled device or reader module
	//                  PICC for proximity integrated circuit card or tag)
	//          and their protypes are defined in the header file.
	//          Each command for a PICC consists of a PCD command. Therefore
	//          the function M500PcdCmd is very important for the understanding
	//          of the communication.
	//
	//          The basic functionality is provided by the interrupt service
	//          routine (ISR), which closely works together with the function
	//          M500PcdCmd. All kinds of interrupts are serviced by the 
	//          same ISR. 
	
	
	// inline structure in order to reset the communication channel between 
	// function and ISR
	#define ResetInfo(info)    \
	        info.cmd            = 0; \
	        info.status         = MI_OK;\
	        info.irqSource      = 0;   \
	        info.nBytesSent     = 0;   \
	        info.nBytesToSend   = 0;  \
	        info.nBytesReceived = 0;  \
	        info.nBitsReceived  = 0;   \
	        info.collPos        = 0;
	
	// struct definition for a communication channel between function and ISR
	typedef struct 
	     {
	        unsigned char  cmd;           //!< command code 
	        char           status;        // communication status
	        unsigned char  nBytesSent;    // how many bytes already sent
	        unsigned char  nBytesToSend;  // how many bytes to send
	        unsigned char  nBytesReceived;// how many bytes received
	        unsigned short nBitsReceived; // how many bits received
	        unsigned char  irqSource;     // which interrupts have occured
	        unsigned char  collPos;       // at which position occured a
	                                      // collision
	     } MfCmdInfo;
	
	// modul variables 
	extern	 unsigned char xdata *GpBase;
	
	static   unsigned char idata MFIFOLength = DEF_FIFO_LENGTH; // actual FIFO length
	
	static   unsigned char xdata MKeys[16][12]; // storage for authentication keys
	                                  // in order to provide a calling 
	                                  // compatible interface to old libraries
	                         // Other reader modules keep several sets
	                         // of keys in an E2PROM. In this case,
	                         // these keys are stored in the uC and
	                         // transfered to the reader module 
	                         // before authentication
	
	// Information concerning data processing
	     // send buffer for general use
	static   volatile unsigned char xdata MSndBuffer[SND_BUF_LEN];
	     // receive buffer for general use
	static   volatile unsigned char xdata MRcvBuffer[RCV_BUF_LEN];
	     // info struct for general use
	static   volatile MfCmdInfo     MInfo;                  
	
	// Interrupt service routine
	// 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;     
	
	// 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];
	
	// Timer 2
	bit		T2IR	 	= 0;	// Timer2 timeout flag
	unsigned int 	CountDown	= 0;	// Timeout counter with 50us resolution
	
	sbit    RC500RST        	= P3^3;
	sbit    LED	        	= P3^5;
	
	///////////////////////////////////////////////////////////////////////////////
	//             Prototypes for local functions 
	///////////////////////////////////////////////////////////////////////////////
	
	void start_timeout(unsigned int _50us);
	void stop_timeout(void);
	
	// _____________________________________________________________________________
	//
	//  FUNCTION: M500PcdSetTmo
	//        IN: tmoLength   1  ... 1.0 ms timeout periode
	//                        2  ... 1.5 ms timeout periode
	//                        3  ... 6.0 ms timeout periode
	//        		          4  ... 9.6 ms timeout period
	//                        5  ... 38.5 ms timeout period
	//                        6  ... 154 ms timeout period
	//                        7  ... 616.2 ms timeout period
	//       OUT: -
	//    RETURN: 
	//   COMMENT: Set timeout length of the reader internal timer.
	//               
	void M500PcdSetTmo(unsigned char tmoLength);
	
	// _____________________________________________________________________________
	//
	//  FUNCTION: M500PcdCmd
	//        IN: cmd    PCD_IDLE
	//                   PCD_WRITEE2
	//                   PCD_READE2
	//                   PCD_LOADCONFIG
	//                   PCD_LOADKEYE2
	//                   PCD_AUTHENT1
	//                   PCD_CALCCRC
	//                   PCD_AUTHENT2
	//                   PCD_RECEIVE
	//                   PCD_LOADKEY
	//                   PCD_TRANSMIT
	//                   PCD_TRANSCEIVE
	//                   PCD_RESETPHASE
	//                   for a detailed description of the parameter values, please
	//                   have a look on the header file of the reader register
	//                   definitions.
	//            send      byte stream of variable length, which should be send to
	//                      the PICC, the length of stream has to be specified
	//                      in the info - structure
	//       OUT: rcv    byte stream of variable length, which was received 
	//                      from the PICC or PCD
	//            info      communication and status structure
	//    RETURN: 
	//   COMMENT: This function provides the central interface to the reader module.
	//            Depending on the "cmd"-0value, 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. Immediate after 
	//            enabling the interrupts, the LoAlert interrupt is activated.
	//            The ISR writes the data to the FIFO. This function is not involved
	//            in writing or fetching data from FIFO, all work is done by the 
	//            ISR.After command completion, the error status is evaluated and 
	//            returned to the calling function.
	//
	char M500PcdCmd(unsigned char cmd,
	            volatile unsigned char* send, 
	            volatile unsigned char* rcv,
	            volatile MfCmdInfo *info);
	
	// _____________________________________________________________________________
	//
	//  FUNCTION: SetBitMask
	//        IN: reg      register address
	//            mask     bit mask to set
	//       OUT: -
	//    RETURN: 
	//   COMMENT:  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.
	//
	char SetBitMask(unsigned char reg,unsigned char mask);
	
	// _____________________________________________________________________________
	//
	//  FUNCTION: ClearBitMask
	//        IN: reg      register address
	//            mask     bit mask to clear
	//       OUT: -
	//    RETURN: 
	//   COMMENT:  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.
	//
	char ClearBitMask(unsigned char reg,unsigned char mask);
	
	// _____________________________________________________________________________
	//
	//  FUNCTION: FlushFIFO
	//        IN: -
	//       OUT: -
	//    RETURN: 
	//   COMMENT: All remaining date in the FIFO of the reader module is 
	//            erased by this function. Before wrinting new data or
	//            starting a new command, all remaining data from former 
	//            commands should be deleted. Please note, that in 
	//            normal operation, never data should be left, that means
	//            that a call to this function should not be necessary.
	//
	void FlushFIFO(void);
	
	// _____________________________________________________________________________
	//
	//  FUNCTION: M500PiccAuthState
	//        IN: auth_mode
	//            snr
	//            sector
	//       OUT: -
	//    RETURN: 
	//   COMMENT: 
	//
	char M500PiccAuthState(unsigned char auth_mode,// PICC_AUTHENT1A, PICC_AUTHENT1B
	                   unsigned char *snr,    // 4 byte serial number
	                   unsigned char sector); // 0 <= sector <= 15  
	                                        // sector address for authentication
	
	//////////////////////////////////////////////////////////////////////
	//           E X C H A N G E   B Y T E   S T R E A M
	///////////////////////////////////////////////////////////////////////
	char ExchangeByteStream(unsigned char Cmd,
	                    unsigned char *send_data,
	                    unsigned char send_bytelen,
	                    unsigned char *rec_data,  
	                    unsigned char *rec_bytelen);
	
	///////////////////////////////////////////////////////////////////////////////
	//                  Interrupt Handler RC500
	///////////////////////////////////////////////////////////////////////////////
	void RC500ISR (void) interrupt 0 using 1    //Ext0 interrupt
	{
	static unsigned char idata irqBits;
	static unsigned char idata irqMask;            
	static unsigned char idata nbytes;
	static unsigned char idata cnt;
	
	IE0 = 0; 	// Clear interrupt request flag
	
	if (MpIsrInfo && MpIsrOut && MpIsrIn)  // transfer pointers have to be set
	                                      // correctly
	{
	  while( ReadRawIO(RegPrimaryStatus) & 0x08) // loop while IRQ pending
	                                            // Attention: IRQ bit is 
	                                            // inverted when used with
	                                            // low activ IRQ
	  {
	     irqMask = ReadRawIO(RegInterruptEn); // read enabled interrupts
	     // read pending interrupts
	     irqBits = ReadRawIO(RegInterruptRq) & irqMask;
	     MpIsrInfo->irqSource |= irqBits; // save pending interrupts
	     //************ LoAlertIRQ ******************
	     if (irqBits & 0x01)    // LoAlert
	     {  
	        nbytes = MFIFOLength - ReadRawIO(RegFIFOLength);
	        // less bytes to send, than space in FIFO
	        if ((MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent) <= nbytes)
	        {
	           nbytes = MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent;
	           WriteRawIO(RegInterruptEn,0x01); // disable LoAlert IRQ
	        }
	        // write remaining data to the FIFO
	        for ( cnt = 0;cnt < nbytes;cnt++)
	        {
	           WriteRawIO(RegFIFOData,MpIsrOut[MpIsrInfo->nBytesSent]);
	           MpIsrInfo->nBytesSent++;
	        }
	        WriteRawIO(RegInterruptRq,0x01);  // reset IRQ bit
	     }
	  
	     //************* TxIRQ Handling **************
	     if (irqBits & 0x10)       // TxIRQ
	     {
	        WriteRawIO(RegInterruptRq,0x10);    // reset IRQ bit 
	        WriteRawIO(RegInterruptEn,0x82);    // enable HiAlert Irq for
	                                       // response
	        if (MpIsrInfo->cmd == PICC_ANTICOLL1) 	// if cmd is anticollision
	    {                                           // switch off parity generation
	           WriteRawIO(RegChannelRedundancy,0x02);	// RXCRC and TXCRC disable, parity disable
	    }	
	     }
	
	     //************* HiAlertIRQ or RxIRQ Handling ******************
	     if (irqBits & 0x0E) // HiAlert, Idle or RxIRQ
	     {
	        // read some bytes ( length of FIFO queue)              
	        // into the receive buffer
	        nbytes = ReadRawIO(RegFIFOLength);
	        // read date from the FIFO and store them in the receive buffer
	        for ( cnt = 0; cnt < nbytes; cnt++)               
	        {
	           MpIsrIn[MpIsrInfo->nBytesReceived] = ReadRawIO(RegFIFOData);
	           MpIsrInfo->nBytesReceived++;
	        }
	        WriteRawIO(RegInterruptRq,0x0A & irqBits);  
	                                   // reset IRQ bit - idle irq will
	                                   // be deleted in a seperate section
	     }   
	
	     //************** IdleIRQ Handling ***********
	     if (irqBits & 0x04)     // Idle IRQ
	     {
	        WriteRawIO(RegInterruptEn,0x20); // disable Timer IRQ
	        WriteRawIO(RegInterruptRq,0x20); // disable Timer IRQ request
	        irqBits &= ~0x20;   // clear Timer IRQ in local var
	        MpIsrInfo->irqSource &= ~0x20; // clear Timer IRQ in info var
	                                    // when idle received, then cancel
	                                    // timeout
	        WriteRawIO(RegInterruptRq,0x04);  // reset IRQ bit 
	        // status should still be MI_OK
	        // no error - only used for wake up
	     }
	   
	     //************* TimerIRQ Handling ***********
	     if (irqBits & 0x20)       // timer IRQ
	     {
	        WriteRawIO(RegInterruptRq,0x20); // reset IRQ bit 
	        MpIsrInfo->status = MI_NOTAGERR; // timeout error
	                                         // otherwise ignore the interrupt
	     }
	     
	  }
	}
	}
	
	///////////////////////////////////////////////////////////////////////
	//         S e t   T i m e o u t   L E N G T H
	///////////////////////////////////////////////////////////////////////
	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) 

⌨️ 快捷键说明

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