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

📄 fm1702.c

📁 ARM_CORTEX-M3应用实例开发详解光盘
💻 C
📖 第 1 页 / 共 2 页
字号:
	char buf[4];

	// 0x80开始是密钥存放区, 并按12字节连续存放
	addr = 0x80 + 12 * mif_sec;
	buf[0] = addr & 0xFF;
	buf[1] = (addr & 0x0100) >> 8;
	if (cmd_send(LoadKeyE2, buf, 2) != FM1702_OK) {
 		return err_chk(__FUNCTION__, __LINE__);
	}
	return FM1702_OK;
}

// 关闭电磁波载波发射
int fm1702_mif_no_energy(int usec) {
	// 对于某些卡片, 只有第一次上电时REQ操作才会有回复
	// 这样, 以下代码关闭能量发送, 用于对付这种卡片.
	// 而对正常卡片没有影响
	FM1702_SET_REG(TxControl_Reg, FM1702_GET_REG(TxControl_Reg) & ~0x03);
	sleep_us(usec);
	FM1702_SET_REG(TxControl_Reg, FM1702_GET_REG(TxControl_Reg) | 0x03);
	return FM1702_OK;
}

// 给MIFARE卡发送HALT命令
int fm1702_mif_halt(void) {
	//int i;
	int rlen;
	char buf[3];
	
	//FM1702_SET_REG(BitFraming_Reg, 0x07);		//最后一个字节发送7bit	
	FM1702_SET_REG(CRCPresetLSB, 0x63);
	//0
	//0	CRCMSBFirst, 0 = 数据流低位先进入CRC运算
	//0	CRC3309, 0 = 使用ISO14443A CRC算法
	//0	CRC8, 0 = 计算16bit CRC
	//0	RxCRCEn, 0 = 关闭接收CRC                 *****
	//0	TxCRCEn, 0 = 关闭发送CRC
	//1	ParityOdd, 1 = 奇校验
	//1	ParityEn, 1 = 每发送字节后插入校验位
	FM1702_SET_REG(ChannelRedundancy_Reg, 0x03);	// 关闭接收CRC
	FM1702_SET_REG(CWConductance_Reg, CW_VAL);


	buf[0] = CMD_HALTA;
	buf[1] = 0x0;
	if (cmd_send(Transmit, buf, 2) != FM1702_OK) {
 		//return err_chk(__FUNCTION__, __LINE__);
		rlen = err_chk(__FUNCTION__, __LINE__);
		if ((rlen & 0x3F) != 0) {
			return rlen;
		}
	}
#if 0
	// wait command send ok
	for(i = 10; i > 0; i--) {
		if (fifo_len() == 0) break;
		sleep_us(1000);
	}
#endif
	return FM1702_OK;	
}

// 对放入FM1702操作范围内的卡片request操作
int fm1702_mif_req(int f_all) {
	char buf[4];
	int rlen;

	FM1702_SET_REG(CRCPresetLSB, 0x63);
	FM1702_SET_REG(CWConductance_Reg, CW_VAL);
	FM1702_SET_REG(BitFraming_Reg, 0x07);		//最后一个字节发送7bit
	FM1702_SET_REG(ChannelRedundancy_Reg, 0x03);	// 关闭接收CRC
	//bit3, CryptolOn,  0 = 关闭加密, 发送完自动打开
	FM1702_SET_REG(Control_Reg, FM1702_GET_REG(Control_Reg) & (~0x08));

	buf[0] = f_all? CMD_WAKEUPA: CMD_REQA;
	if (cmd_send(Transceive, buf, 1) != FM1702_OK) {
		//return err_chk(__FUNCTION__, __LINE__);
		rlen = err_chk(__FUNCTION__, __LINE__);
		if ((rlen & 0x3F) != 0) {
			return rlen;
		}
	}
#if 0
	fm1702_timeout(&stm, 0);
	while (fifo_len() < 2) {
		if (fm1702_timeout(&stm, 10)) break;
	}
#endif
	if ((
	//rlen = 
	read_fifo(buf)) > 0) {
#if 0
		debug_buf("mif_req(): RECV", buf, rlen);
#endif
		if (detect_req(buf)) {
			return FM1702_OK;
		}		
	}
	// printf("fm1702_mif_req(): error req");
	return FM1702_ERR_REQ;
}

// 对放入FM1702操作范围内的卡片做防冲突检测
int fm1702_mif_anticol(char* uid) {
	char p_row = 0;
	char row = 0;
	char col = 0;
	char buf[8];
	int r, rlen;

	FM1702_SET_REG(CRCPresetLSB, 0x63);
	FM1702_SET_REG(CWConductance_Reg, CW_VAL);
	FM1702_SET_REG(ModConductance_Reg, 0x3F);
	//FM1702_SET_REG(BitFraming_Reg, 0x07);	//最后一个字节发送7bit
	FM1702_SET_REG(ChannelRedundancy_Reg, 0x03);	// 关闭接收CRC

	buf[0] = CMD_ANTICOL;
	buf[1] = 0x20;
	r = cmd_send(Transceive, buf, 2);
	
	while (1) {
		if (r != FM1702_OK) {
			//return err_chk(__FUNCTION__, __LINE__);
			rlen = err_chk(__FUNCTION__, __LINE__);
			if ((rlen & 0x3F) != 0) {
				return rlen;
			}
		}
		if ((r = read_fifo(buf)) <= 0) {
			return err_chk(__FUNCTION__, __LINE__);
		}
		trans_uid(((int)row << 8) + col, uid, buf, r);

		r = FM1702_GET_REG(ErrorFlag_Reg) & 0x01;
		if (r == 0x00) {
			if (!check_uid(buf)) {
				return FM1702_ERR_SERNR;
			}
			break;
		}

		r = FM1702_GET_REG(CollPos_Reg);
		row = r >> 3;
		col = r & 0x07;
		p_row += row;
		
		set_bitframe(((int)p_row << 8) + col, buf);

		buf[0] = CMD_ANTICOL;
		memcpy(&buf[2], &uid[0], p_row + 1);

		row = (col != 0) ? p_row + 1: p_row;
		r = cmd_send(Transceive, buf, row + 2);
	}
	return FM1702_OK;
}

//对FM1702操作范围内的某张卡进行选择
int fm1702_mif_sel(char* uid) {
	int rlen;
	char dummy;
	char buf[8];

	FM1702_SET_REG(CRCPresetLSB, 0x63);
	FM1702_SET_REG(CWConductance_Reg, CW_VAL);

	buf[0] = CMD_SELECT;
	buf[1] = 0x70;
	memcpy(&buf[2], uid, 5);

	FM1702_SET_REG(ChannelRedundancy_Reg, 0x0F);	// 打开发送及接收CRC
	if (cmd_send(Transceive, buf, 7) != FM1702_OK) {
		return FM1702_ERR_NOTAG;
	}
	dummy = FM1702_GET_REG(ErrorFlag_Reg);
	if ((dummy & 0x0E) != 0) {
		//return err_chk(__FUNCTION__, __LINE__);
		rlen = err_chk(__FUNCTION__, __LINE__);
		if ((rlen & 0x3F) != 0) {
			return rlen;
		}
	}

	if (read_fifo(buf) < 1) {
		//return err_chk(__FUNCTION__, __LINE__);
		rlen = err_chk(__FUNCTION__, __LINE__);
		if ((rlen & 0x3F) != 0) {
			return rlen;
		}
	}
	if (buf[0] == 0x08 ||
	  buf[0] == 0x88 ||
	  buf[0] == 0x53) {
	  	return FM1702_OK;
	}
	//return err_chk(__FUNCTION__, __LINE__);
	rlen = err_chk(__FUNCTION__, __LINE__);
	if ((rlen & 0x3F) != 0) {
		return rlen;
	}
	return FM1702_OK;
}

//密码认证的过程
int fm1702_mif_auth(char* uid, int mif_blk) {
	char buf[8];

	FM1702_SET_REG(CRCPresetLSB, 0x63);
	FM1702_SET_REG(CWConductance_Reg, CW_VAL);
	FM1702_SET_REG(ModConductance_Reg, 0x3F);
	//bit3, CryptolOn,  0 = 关闭加密, 发送完自动打开
	FM1702_SET_REG(Control_Reg, FM1702_GET_REG(Control_Reg) & ~(0x08));
	FM1702_SET_REG(ChannelRedundancy_Reg, 0x0F);	// 打开发送及接收CRC
	
	buf[0] = CMD_AUTHA;
	buf[1] = mif_blk;
	memcpy(&buf[2], uid, 4);
	//debug_buf("Authent1", buf, 6);

	if (cmd_send(Authent1, buf, 6) != FM1702_OK) {
		return FM1702_ERR_NOTAG;
	}
	if ((FM1702_GET_REG(ErrorFlag_Reg) & 0x0E) != 0) {
		return err_chk(__FUNCTION__, __LINE__);
	}

	if (cmd_send(Authent2, buf, 0) != FM1702_OK) {
		return FM1702_ERR_NOTAG;
	}
	if ((FM1702_GET_REG(ErrorFlag_Reg) & 0x0E) != 0) {
		return err_chk(__FUNCTION__, __LINE__);
	}

	if ((FM1702_GET_REG(Control_Reg) & 0x08) == 0x08) {
		return FM1702_OK;
	}
	return FM1702_ERR_AUTH;
}

// 读MIFARE卡某块的数据
//返回读取字节数,或者错误码
int fm1702_mif_read(int mif_blk, char* buf) {
	char rwbuf[4];
	int rlen;

	FM1702_SET_REG(CRCPresetLSB, 0x63);
	FM1702_SET_REG(CWConductance_Reg, CW_VAL);
	FM1702_SET_REG(ModConductance_Reg, 0x3F);
	//FM1702_SET_REG(ChannelRedundancy_Reg, 0x07);	// 关闭接收CRC
	FM1702_SET_REG(ChannelRedundancy_Reg, 0x0F);	// 打开发送及接收CRC
	//FM1702_SET_REG(InterruptRq_Rg, 0x7F);

	rwbuf[0] = CMD_READ;
	rwbuf[1] = mif_blk;
	if ((rlen = cmd_send(Transceive, rwbuf, 2)) != FM1702_OK) {
		//return FM1702_ERR_NOTAG;
		return rlen;
	}

	if ((FM1702_GET_REG(ErrorFlag_Reg) & 0x0E) != 0) {
		return err_chk(__FUNCTION__, __LINE__);
	}
	//sleep_us(5000);
	rlen = read_fifo(buf);
	if (rlen == 0x10 || rlen == 0x04) {
		return rlen;
	}
	return err_chk(__FUNCTION__, __LINE__);
}

// 写数据到MIFARE卡某块
// 返回FM1702_OK 或错误码
int fm1702_mif_write(int mif_blk, char* buf) {
	char rwbuf[4];
	int rlen;

	FM1702_SET_REG(CRCPresetLSB, 0x63);
	FM1702_SET_REG(CWConductance_Reg, CW_VAL);
	FM1702_SET_REG(ChannelRedundancy_Reg, 0x07);	// 关闭接收CRC

	rwbuf[0] = CMD_WRITE;
	rwbuf[1] = mif_blk;
	if ((rlen = cmd_send(Transceive, rwbuf, 2)) != FM1702_OK) {
		printf("\r\ncmd_send() = %d", rlen);
		//return FM1702_ERR_NOTAG;
		return rlen;
	}
#if 0
	fm1702_timeout(&stm, 0);
	while (fifo_len() != 1) {
		if (fm1702_timeout(&stm, 10))
			break;
	}
#endif
	//sleep_us(1000);
	rlen = fifo_len();
	if (read_fifo(rwbuf) != 1) {
		return err_chk(__FUNCTION__, __LINE__);
	}
	if (rwbuf[0] != 0x0A) {
		return err_chk(__FUNCTION__, __LINE__);
	}
	if (cmd_send(Transceive, buf, 16) != FM1702_OK) {
		return err_chk(__FUNCTION__, __LINE__);
	}

	//sleep(12);
#if 1
	fm1702_timeout(&stm, 0);
	while (fifo_len() < 1) {
		if (fm1702_timeout(&stm, 10)) break;
	}
#endif
	if (read_fifo(rwbuf) != 1) {
		return err_chk(__FUNCTION__, __LINE__);
	}
	if (rwbuf[0] != 0x0A) {
		return err_chk(__FUNCTION__, __LINE__);
	}
	return FM1702_OK;
}


/////////////////////////////////////TEST CODE//////////////////////////////////


#if defined(REQ_TEST)
int iso14443_cmd(char* buf, int len) {
	//int i;
	static int d_us = 1;
	int rlen;
	static char rsvbuf[65];

	printf("\r\nd_us = %d us", d_us);
	
	//FM1702_SET_REG(BitFraming_Reg, 0x07);	//最后一个字节发送7bit	
	//0
	//0	CRCMSBFirst, 0 = 数据流低位先进入CRC运算
	//0	CRC3309, 0 = 使用ISO14443A CRC算法
	//0	CRC8, 0 = 计算16bit CRC
	//0	RxCRCEn, 0 = 关闭接收CRC                 *****
	//0	TxCRCEn, 0 = 关闭发送CRC
	//1	ParityOdd, 1 = 奇校验
	//1	ParityEn, 1 = 每发送字节后插入校验位
	FM1702_SET_REG(ChannelRedundancy_Reg, 0x03);
	FM1702_SET_REG(CWConductance_Reg, CW_VAL);

	rsvbuf[0] = CMD_HALTA;
	rsvbuf[1] = 0x0;
	if (cmd_send(Transmit, rsvbuf, 2) != 0) {
 		return err_chk(__FUNCTION__, __LINE__);
	}
#if 0
	// wait command send ok
	for(i = 10; i > 0; i--) {
		if (fifo_len() == 0) break;
		sleep_us(1000);
	}
#endif
	FM1702_SET_REG(CWConductance_Reg, CW_VAL);
	FM1702_SET_REG(BitFraming_Reg, 0x07);	//最后一个字节发送7bit
	FM1702_SET_REG(ChannelRedundancy_Reg, 0x03);	//关闭接收CRC

	//bit3, CryptolOn,  0 = 关闭加密, 发送完自动打开
	FM1702_SET_REG(Control_Reg, FM1702_GET_REG(Control_Reg) & ~(0x08));

	//buf[0] = CMD_WAKEUPA;
	//len = 1;
#if 0
	debug_buf("cmd_send(): ", buf, len);
#endif
	//printf("c\r\n");
	sleep_us(d_us);
	d_us += 50;

	if (cmd_send(Transceive, buf, len) != 0) {
		return err_chk(__FUNCTION__, __LINE__);
	}

#if 0
	fm1702_timeout(&stm, 0);
	while (fifo_len() < 2) {
		if (fm1702_timeout(&stm, 10)) break;
	}
#endif
	if ((rlen = read_fifo(rsvbuf)) > 0) {
		printf("\r\n%s()", __FUNCTION__);
		debug_buf("RECV", rsvbuf, rlen);
		return rlen;
	}
	return FM1702_OK;
}


int iso14443_test(void) {

	while (1) {
		char sndbuf[64];
		int cnt = 1;
#if 1
		int i, dummy;
		printf("\r\ninput bytes?");
		ascanf("%d", &cnt);
		for (i = 0; i < cnt; i++) {
			ascanf("%X", &dummy);
			sndbuf[i] = (dummy & 0xFF);
		}
#endif

		if ((cnt = iso14443_cmd(sndbuf, cnt)) >= 0) {
			printf("\r\niso14443 cmd ok %d", cnt);
		} else {
			printf("\r\n");
		}
		//sleep(500);
	}
}

#endif

#if FM1702_CW_DEBUG
int fm1702_cw_debug(void) {
	int ch = 0;

	if ((ch = peekch()) == EOF || ch != ' ') {
		return 0;
	}

#if 0
	printf("\r\ninput CWConductance_Reg Values?");
	if (++CW_VAL > 0x3F) {
		CW_VAL = 0;
	}
	//ascanf("%d", &CW_VAL);
	printf("=%d", CW_VAL);
#endif

#if 0
	printf("\r\ninput ModWidth_Reg Values?");
	if (++MOD_W_VAL > 0xFF) {
		MOD_W_VAL = 0;
	}
	printf("=%d", MOD_W_VAL);
	//ascanf("%d", &MOD_W_VAL);
#endif
	init_fm1702();
	return 0;
}

#if FM1702_CW_DEBUG
			fm1702_cw_debug();
#endif

#endif

/************************************END OF FILE******************************/

⌨️ 快捷键说明

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