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;i 1000) { 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