www.pudn.com > mifare_wiegand(1.1).rar > M500AuC.c


#define M500_GLOBALS 
 
#include  
#include  
#include  
#include  
 
#include "Mfreg500.h" 
#include "MfErrNo.h" 
//#include "reg52.h" 
#include "M500AuC.h" 
#include "wiegand.h" 
 
#define GetRegPage(addr)    (0x80 | (addr>>3)) 
#define nocard			    0 
#define mifare1			    1 
#define mifarepro		    2 
#define mifarelight		    3 
#define unknowncard		    4 
#define NO_TIMER2           1 
#define Debug 
 
sbit SPEAKER    =   P1^7; 
sbit GREEN		=   P1^4;  
sbit RED		=   P1^3; 
/////////////////////////////////////////////////////////////////////// 
// 往一个地址写一个数据 
/////////////////////////////////////////////////////////////////////// 
void WriteRawIO(unsigned char Address,unsigned char value) 
{ 
	XBYTE[Address]=value; 
} 
 
/////////////////////////////////////////////////////////////////////// 
// 从一个地址读出一个数据 
/////////////////////////////////////////////////////////////////////// 
unsigned char ReadRawIO(unsigned char Address) 
{ 
	return XBYTE[Address]; 
} 
 
/////////////////////////////////////////////////////////////////////// 
// 往一个地址写一个数据(EEPROM) 
/////////////////////////////////////////////////////////////////////// 
void WriteIO(unsigned char Address, unsigned char value) 
{ 
    WriteRawIO(0x00,GetRegPage(Address));   
    WriteRawIO(Address,value);               
} 
 
/////////////////////////////////////////////////////////////////////// 
// 从一个地址读出一个数据(EEPROM) 
/////////////////////////////////////////////////////////////////////// 
unsigned char ReadIO(unsigned char Address) 
{ 
   WriteRawIO(0x00,GetRegPage(Address)); 
   return ReadRawIO(Address);                     
}   
 
/////////////////////////////////////////////////////////////////////// 
// 设置定时时间 
/////////////////////////////////////////////////////////////////////// 
void M500PcdSetTmo(unsigned char 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; 
    }      
} 
 
/////////////////////////////////////////////////////////////////////// 
// Request Command defined in ISO14443(Mifare) 
/////////////////////////////////////////////////////////////////////// 
char  M500PcdCmd(unsigned char cmd, 
               volatile unsigned char data *rcv, 
                MfCmdInfo idata *info) 
{ 
    char          idata status    = MI_OK; 
    char          idata tmpStatus ; 
    unsigned char idata lastBits; 
    unsigned int  idata timecnt = 0; 
    unsigned char idata irqEn = 0x00; 
    unsigned char idata waitFor = 0x00; 
    unsigned char idata timerCtl  = 0x00; 
 
    WriteIO(RegInterruptEn,0x7F); 
    WriteIO(RegInterruptRq,0x7F); 
    WriteIO(RegCommand,PCD_IDLE);  
 
    FlushFIFO();      
    MpIsrInfo = info;   
    MpIsrOut = rcv; 
    info->irqSource = 0x00; 
    switch(cmd) 
    { 
        case PCD_IDLE:                 
            irqEn = 0x00; 
            waitFor = 0x00; 
            break; 
        case PCD_WRITEE2:             
            irqEn = 0x11; 
            waitFor = 0x10; 
            break; 
        case PCD_READE2:      
            irqEn = 0x07; 
            waitFor = 0x04; 
            break; 
        case PCD_LOADCONFIG:   
        case PCD_LOADKEYE2:    
        case PCD_AUTHENT1:     
            irqEn = 0x05; 
            waitFor = 0x04; 
            break; 
        case PCD_CALCCRC: 
            irqEn = 0x11; 
            waitFor = 0x10; 
            break; 
        case PCD_AUTHENT2:  
            irqEn = 0x04; 
            waitFor = 0x04; 
            break; 
        case PCD_RECEIVE:      
            info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4); 
            irqEn = 0x06; 
            waitFor = 0x04; 
            break; 
        case PCD_LOADKEY:  
            irqEn = 0x05; 
            waitFor = 0x04; 
            break; 
        case PCD_TRANSMIT:  
            irqEn = 0x05; 
            waitFor = 0x04; 
            break; 
        case PCD_TRANSCEIVE:  
	        info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4); 
            irqEn = 0x3D; 
            waitFor = 0x04; 
            break; 
        default: 
            status = MI_UNKNOWN_COMMAND; 
    }         
    if (status == MI_OK) 
    { 
        irqEn |= 0x20;                      
        waitFor |= 0x20;       
        timecnt=1000; 
        WriteIO(RegInterruptEn,irqEn | 0x80);  
        WriteIO(RegCommand,cmd);      
        while (!(MpIsrInfo->irqSource & waitFor||!(timecnt--))); 
        WriteIO(RegInterruptEn,0x7F);          
        WriteIO(RegInterruptRq,0x7F);           
        SetBitMask(RegControl,0x04);           
        WriteIO(RegCommand,PCD_IDLE);          
        if (!(MpIsrInfo->irqSource & waitFor))    
        {                                
            status = MI_ACCESSTIMEOUT; 
        } 
        else 
        { 
            status = MpIsrInfo->status;            
        } 
        if (status == MI_OK)                     
        { 
            if (tmpStatus = (ReadIO(RegErrorFlag) & 0x17)) 
            { 
                if (tmpStatus & 0x01) 
                { 
                    info->collPos = ReadIO(RegCollPos); 
                    status = MI_COLLERR; 
                } 
                else 
                { 
                    info->collPos = 0; 
                    if (tmpStatus & 0x02)   
                    { 
                        status = MI_PARITYERR; 
                    } 
                } 
                if (tmpStatus & 0x04)    
                { 
                    status = MI_FRAMINGERR; 
                } 
                if (tmpStatus & 0x10)    
                { 
                    FlushFIFO(); 
                    status = MI_OVFLERR; 
                } 
 	            if (tmpStatus & 0x08)  
	            { 
                    status = MI_CRCERR; 
	            }	 
                if (status == MI_OK) 
                    status = MI_NY_IMPLEMENTED; 
            } 
            if (cmd == PCD_TRANSCEIVE) 
            { 
                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;          
    MpIsrOut  = 0; 
    return status; 
}    
 
/////////////////////////////////////////////////////////////////////// 
// 置一个bit 
/////////////////////////////////////////////////////////////////////// 
char SetBitMask(unsigned char reg,unsigned char mask)   
{ 
    char idata tmp = 0x00; 
 
    tmp = ReadIO(reg); 
    WriteIO(reg,tmp | mask);  // set bit mask 
    return 0x00; 
} 
 
/////////////////////////////////////////////////////////////////////// 
// 清一个bit 
/////////////////////////////////////////////////////////////////////// 
char ClearBitMask(unsigned char reg,unsigned char mask)   
{ 
    char idata tmp = 0x00; 
 
    tmp = ReadIO(reg); 
    WriteIO(reg,tmp & ~mask);  // clear bit mask 
    return 0x00; 
} 
 
/////////////////////////////////////////////////////////////////////// 
/////////////////////////////////////////////////////////////////////// 
void FlushFIFO(void) 
{   
    SetBitMask(RegControl,0x01); 
} 
 
/////////////////////////////////////////////////////////////////////// 
// Set card in HALT-state 
// 终止卡的操作 
/////////////////////////////////////////////////////////////////////// 
char M500PiccHalt(void) 
{ 
    char idata status = MI_CODEERR; 
 
    // ************* Cmd Sequence **********************************  
    ResetInfo(MInfo);    
    SerBuffer[0] = PICC_HALT ;      // Halt command code 
    SerBuffer[1] = 0x00;            // dummy address 
    MInfo.nBytesToSend = 2; 
    status = M500PcdCmd(PCD_TRANSCEIVE, 
                       SerBuffer, 
                       &MInfo);    
    if (status) 
    { 
        // timeout error ==> no NAK received ==> OK 
        if (status == MI_NOTAGERR || status == MI_ACCESSTIMEOUT) 
        { 
            status = MI_OK; 
        } 
    } 
    //reset command register - no response from tag 
    WriteIO(RegCommand,PCD_IDLE); 
    return status;  
} 
 
/////////////////////////////////////////////////////////////////////// 
// Reset the MF RC500  
/////////////////////////////////////////////////////////////////////// 
char M500PcdReset(void) 
{ 
    char idata status = MI_OK; 
    unsigned int idata timecnt=0; 
     
    RC500RST = 0;   
    delay_1ms(25);  
    RC500RST = 1;   
    delay_50us(200);  
    RC500RST = 0;   
    delay_50us(50); 
    timecnt=1000; 
    while ((ReadIO(RegCommand) & 0x3F) && timecnt--); 
    if(!timecnt) 
    { 
        status = MI_RESETERR; 
    } 
    if (status == MI_OK) 
    { 
        //WriteIO(RegPage,0x80); 
        if (ReadIO(RegCommand) != 0x00) 
        {                            
            status = MI_INTERFACEERR; 
        } 
    } 
    return status; 
} 
 
/////////////////////////////////////////////////////////////////////// 
// Configures the MF RC500 
/////////////////////////////////////////////////////////////////////// 
char M500PcdConfig(void) 
{ 
    char idata status; 
 
    if ((status = M500PcdReset()) == MI_OK) 
    { 
        WriteIO(RegClockQControl,0x00); 
        WriteIO(RegClockQControl,0x40); 
        delay_50us(2);   
        ClearBitMask(RegClockQControl,0x40); 
        WriteIO(RegBitPhase,0xAD);       
        WriteIO(RegRxThreshold,0xFF);    
        WriteIO(RegRxControl2,0x01); 
        WriteIO(RegFIFOLevel,0x1A); 
        WriteIO(RegTimerControl,0x02); 
        WriteIO(RegIRqPinConfig,0x03);  
        M500PcdRfReset(1);                
    } 
    return status; 
} 
 
/////////////////////////////////////////////////////////////////////// 
// Select Command defined in ISO14443(MIFARE) 
/////////////////////////////////////////////////////////////////////// 
char M500PcdMfOutSelect(unsigned char type) 
{ 
    WriteIO(RegMfOutSelect,type&0x7); 
    return MI_OK; 
} 
 
/////////////////////////////////////////////////////////////////////// 
// Request Command defined in ISO14443(MIFARE) 
// Request,Anticoll,Select,return CardType(2 bytes)+CardSerialNo(4 bytes)     
// 寻卡,防冲突,选择卡    返回卡类型(2 bytes)+ 卡系列号(4 bytes) 
/////////////////////////////////////////////////////////////////////// 
char M500PiccCommonRequest(unsigned char req_code,unsigned char *atq) 
{ 
    char idata status = MI_OK; 
	 
    M500PcdSetTmo(3); 
    WriteIO(RegChannelRedundancy,0x03); 
    ClearBitMask(RegControl,0x08); 
    WriteIO(RegBitFraming,0x07);      
    SetBitMask(RegTxControl,0x03);      
    ResetInfo(MInfo); 
    SerBuffer[0] = req_code; 
    MInfo.nBytesToSend = 1;    
     
    status = M500PcdCmd(PCD_TRANSCEIVE,SerBuffer,&MInfo); 
    if (status)      
    { 
        *atq = 0; 
    }  
    else  
    { 
        if (MInfo.nBitsReceived != 16)  
        { 
            *atq = 0; 
            status = MI_BITCOUNTERR; 
        }  
        else  
        { 
            status = MI_OK; 
            memcpy(atq,SerBuffer,2); 
        } 
    } 
    return status;  
} 
 
/////////////////////////////////////////////////////////////////// 
// Cascaded Anti-Collision Command defined in ISO14443(MIFARE) 
// 防冲突 读卡的系列号 MLastSelectedSnr 
/////////////////////////////////////////////////////////////////// 
char M500PiccCascAnticoll (unsigned char bcnt,unsigned char *snr)        
{ 
    char idata status = MI_OK; 
    char idata snr_in[5];//snr_in[4];     
    char idata nbytes = 0; 
    char idata nbits = 0; 
    char idata complete = 0; 
    char idata i        = 0; 
    char idata byteOffset = 0; 
    unsigned char dummyShift1;        
    unsigned char dummyShift2;       
     
    M500PcdSetTmo(106); 
    memcpy(snr_in,snr,5);//memcpy(snr_in,snr,4);    
    
    WriteIO(RegDecoderControl,0x28);  
    ClearBitMask(RegControl,0x08);    
    complete = 0; 
    while (!complete && (status == MI_OK) ) 
    { 
        ResetInfo(MInfo);            
        WriteIO(RegChannelRedundancy,0x03); 
        nbits = bcnt % 8;   
        if(nbits) 
        { 
            WriteIO(RegBitFraming,nbits << 4| nbits);  
            nbytes = bcnt / 8 + 1;    
            if (nbits == 7) 
            { 
                MInfo.cmd = PICC_ANTICOLL1;   
                WriteIO(RegBitFraming,nbits);  
            } 
        }   
        else 
        { 
            nbytes = bcnt / 8; 
        } 
        SerBuffer[0] = 0x93; 
        SerBuffer[1] = 0x20 + ((bcnt/8) << 4) + nbits; 
                
        for (i = 0; i < nbytes; i++)   
        { 
            SerBuffer[i + 2] = snr_in[i]; 
        } 
        MInfo.nBytesToSend   = 2 + nbytes;    
  
        status = M500PcdCmd(PCD_TRANSCEIVE,SerBuffer,&MInfo); 
        if (nbits == 7) 
        { 
            dummyShift1 = 0x00; 
            for (i = 0; i < MInfo.nBytesReceived; i++) 
            { 
                dummyShift2 = SerBuffer[i]; 
                SerBuffer[i] = (dummyShift1 >> (i+1)) | (SerBuffer[i] << (7-i)); 
                dummyShift1 = dummyShift2; 
            } 
            MInfo.nBitsReceived -= MInfo.nBytesReceived;        
            if ( MInfo.collPos ) MInfo.collPos += 7 - (MInfo.collPos + 6) / 9; 
        } 
        if ( status == MI_OK || status == MI_COLLERR)     
        { 
            if ( MInfo.nBitsReceived != (40 - bcnt) ) 
            { 
                status = MI_BITCOUNTERR;  
            }  
            else  
            { 
                byteOffset = 0; 
                if( nbits != 0 )  
                { 
                    snr_in[nbytes - 1] = snr_in[nbytes - 1] | SerBuffer[0]; 
                    byteOffset = 1; 
                } 
 
                for ( i =0; i < (4 - nbytes); i++)      
                { 
                    snr_in[nbytes + i] = SerBuffer[i + byteOffset]; 
                } 
   
                if (status != MI_COLLERR )  
                { 
                    dummyShift2 = snr_in[0] ^ snr_in[1] ^ snr_in[2] ^ snr_in[3]; 
                    dummyShift1 = SerBuffer[MInfo.nBytesReceived - 1]; 
                    if (dummyShift2 != dummyShift1) 
                    { 
                        status = MI_SERNRERR; 
                    }  
                    else    
                    { 
                        complete = 1; 
                    } 
                } 
                else                  
                { 
                    bcnt = bcnt + MInfo.collPos - nbits; 
                    status = MI_OK; 
                } 
            } 
        } 
    } 
    if (status == MI_OK) 
    { 
		snr_in[4]=dummyShift1; 
        memcpy(snr,snr_in,5); 
    } 
    else 
    { 
        memcpy(snr,"00000",5); 
    } 
    ClearBitMask(RegDecoderControl,0x20);  
    
    return status;   
} 
 
/////////////////////////////////////////////////////////////////////// 
// Reset Rf Card 
/////////////////////////////////////////////////////////////////////// 
char M500PcdRfReset(unsigned char ms) 
{ 
    char idata status = MI_OK; 
	 
    if(ms) 
    { 
        ClearBitMask(RegTxControl,0x03);  
        delay_1ms(2);                 
        SetBitMask(RegTxControl,0x03);  
    } 
    else 
    { 
        ClearBitMask(RegTxControl,0x03);   
    } 
    return status; 
} 
 
#pragma noaregs 
 
/////////////////////////////////////////////////////////////////////// 
// Delay 50us 
/////////////////////////////////////////////////////////////////////// 
void delay_50us(unsigned char _50us) 
{ 
    while(_50us--) 
	{ 
	    _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); 
	    _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); 
	    _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); 
	    _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); 
	    _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); 
	    _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); 
	    _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); 
	    _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); 
    } 
} 
 
/////////////////////////////////////////////////////////////////////// 
// Delay 1ms 
/////////////////////////////////////////////////////////////////////// 
void delay_1ms(unsigned char _1ms) 
{ 
#ifndef NO_TIMER2 
    RCAP2LH = RCAP2_1ms; 
    T2LH    = RCAP2_1ms; 
 
    TR2 = TRUE; 
    while (_1ms--) 
    { 
	    while (!TF2); 
	    TF2 = FALSE; 
    } 
    TR2 = FALSE; 
#else 
    while (_1ms--) 
    { 
	    delay_50us(20); 
    } 
#endif 
} 
 
/////////////////////////////////////////////////////////////////////// 
// Delay 10ms 
/////////////////////////////////////////////////////////////////////// 
void delay_10ms(unsigned int _10ms) 
{ 
#ifndef NO_TIMER2 
    RCAP2LH = RCAP2_10ms; 
    T2LH    = RCAP2_10ms; 
     
    TR2 = TRUE; 
    while (_10ms--) 
    { 
	    while (!TF2); 
	    TF2 = FALSE; 
    } 
    TR2 = FALSE; 
#else 
    while (_10ms--) 
    { 
	    delay_50us(19); 
	    if (CmdValid) 
	        return; 
	    delay_50us(20); 
	    if (CmdValid) 
	        return; 
	    delay_50us(20); 
	    if (CmdValid) 
	        return; 
	    delay_50us(20); 
	    if (CmdValid) 
	        return; 
	    delay_50us(20); 
	    if (CmdValid ) 
	        return; 
	    delay_50us(20); 
	    if (CmdValid) 
	        return; 
	    delay_50us(20); 
	    if (CmdValid) 
	        return; 
	    delay_50us(20); 
	    if (CmdValid) 
	        return; 
	    delay_50us(20); 
	    if (CmdValid) 
	        return; 
	    delay_50us(19); 
	    if (CmdValid) 
	        return; 
    } 
#endif 
} 
 
/////////////////////////////////////////////////////////////////////// 
/////////////////////////////////////////////////////////////////////// 
void RC500ISR (void) interrupt 0 using 1     
{ 
    static unsigned char idata irqBits; 
    static unsigned char idata irqMask;             
    static unsigned char idata nbytes; 
    static unsigned char idata cnt; 
	 
    IE0 = 0; 	 
    WriteRawIO(0,0x80); 
    if (MpIsrInfo && MpIsrOut) 
    { 
        while( ReadRawIO(RegPrimaryStatus) & 0x08)  
        { 
            irqMask = ReadRawIO(RegInterruptEn); 
            irqBits = ReadRawIO(RegInterruptRq) & irqMask; 
            MpIsrInfo->irqSource |= irqBits;  
            if (irqBits & 0x01)    
            {   
                nbytes = 64 - ReadRawIO(RegFIFOLength); 
                if ((MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent) <= nbytes) 
                { 
                    nbytes = MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent; 
                    WriteRawIO(RegInterruptEn,0x01); 
                }    
                for ( cnt = 0;cnt < nbytes;cnt++) 
                { 
                    WriteRawIO(RegFIFOData,MpIsrOut[MpIsrInfo->nBytesSent]); 
                    MpIsrInfo->nBytesSent++; 
                } 
                WriteRawIO(RegInterruptRq,0x01);   
            }       
            if (irqBits & 0x10)     
            { 
                WriteRawIO(RegInterruptRq,0x10);     
                WriteRawIO(RegInterruptEn,0x82);    
                if (MpIsrInfo->cmd == PICC_ANTICOLL1) 	 
	            {                                         
                    WriteIO(RegChannelRedundancy,0x02); 
                    WriteRawIO(0,0x80); 
	            }	 
            } 
            if (irqBits & 0x0E)  
            { 
                nbytes = ReadRawIO(RegFIFOLength); 
                for ( cnt = 0; cnt < nbytes; cnt++)                
                { 
                    MpIsrOut[MpIsrInfo->nBytesReceived] = ReadRawIO(RegFIFOData); 
                    MpIsrInfo->nBytesReceived++; 
                } 
                WriteRawIO(RegInterruptRq,0x0A & irqBits);  
            }    
            if (irqBits & 0x04)  
            { 
                WriteRawIO(RegInterruptEn,0x20);  
                WriteRawIO(RegInterruptRq,0x20);  
                irqBits &= ~0x20;  
                MpIsrInfo->irqSource &= ~0x20; 
                WriteRawIO(RegInterruptRq,0x04); 
            } 
            if (irqBits & 0x20)      
            { 
                WriteRawIO(RegInterruptRq,0x20);  
                MpIsrInfo->status = MI_NOTAGERR;  
            } 
        } 
    } 
} 
 
/////////////////////////////////////////////////////////////////////// 
// 接收和发送中断 
/////////////////////////////////////////////////////////////////////// 
void isr_UART(void) interrupt 4 using 1 
{ 
    unsigned char len, i; 
  	unsigned int j=0; 
  	 
  	if(RI) 
	{		 
		len=SBUF; 
		RI=0;	 
		for(i=0;i1000) 
				{ 
				    break; 
				} 
			} 
			if(j<1000) 
			{ 
				RevBuffer[i]=SBUF; 
				RI=0; 
				j=0; 
			} 
			else 
			{ 
			    break; 
			} 
		} 
		if(i==len) 
		{ 
			REN=0; 
			CmdValid=1; 
		} 
	} 
	else if(!RI && TI) 
	{ 
		TI=0; 
		len=RevBuffer[0]; 
		for(i=1;i