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

📄 mfr500.c

📁 程序实现了mfr500对IC卡的读写操作
💻 C
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////////
// 设置定时时间
///////////////////////////////////////////////////////////////////////
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  配置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[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;

⌨️ 快捷键说明

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