📄 fm1702.c
字号:
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 + -