您的位置:首页 > 其它

(10)mifare卡读写器开发心得『转』--整理重发贴

2011-10-24 17:01 295 查看
发信人:xlfdan
发表时间:2003-06-19 20:57:38

--------------------------------------------------------------------------------

请看下面的PHILIPS版权声明,在它的RC500读写软件的开头的地方,

我们贴这些软件违法吗?他们会找我们的麻烦吗?

请回答????

/////////////////////////////////////////////////////////////////////

// Copyright (c), Philips Semiconductors Gratkorn

//

// (C)PHILIPS Electronics N.V.2000

// All rights are reserved. Reproduction in whole or in part is

// prohibited without the written consent of the copyright owner.

// Philips reserves the right to make changes without notice at any time.

// Philips makes no warranty, expressed, implied or statutory, including but

// not limited to any implied warranty of merchantibility or fitness
for any

//particular purpose, or that the use will not infringe any third party patent,

// copyright or trademark. Philips must not be liable
for any loss or damage

// arising from its use.

/////////////////////////////////////////////////////////////////////

发信人:mgl_mcu
发表时间:2003-06-20 09:05:32

--------------------------------------------------------------------------------

u2270b和单片机连接,请问单片机的一个I/O口控制BC846(NPN)三极管,单片机输出的是什么信号?是置高的控制信号呢?还是输出125KHZ的方波信号,请各位大虾指点迷津,谢谢!!

发信人:jiangbo123
发表时间:2003-06-20 17:37:24

--------------------------------------------------------------------------------

我从来没有说过块值不能当普通数据读出呀,只是说卡里寄存器的值不能直接读出,卡里面所有扇区(sector)的所有块(block)里面的数据都是读出的,我想你错误的理解了,下面是我的原话:

你不熟悉所谓钱包到底是什么?

其实所谓钱包就是常说的块值操作,这个每个公司可能叫法不一,其实就是数据在块里的一种特殊的存储格式,这个我在以前的帖子已经讲过。寄存器的值不能直接读出,而只能通过transfer和restore实现和块之间的数据传递。电子钱包块数据全部为0,其实就是说明改块没有进行初始化,没有按照上面提到的特殊存储格式保存数据。因为如果钱包里余额为0时,块里面的数据应该如下(每两位表示一个16进制数):

00000000ffffffff00000000xxyyxxyy

其中xx表示该块的地址,yy是xx的反码

发信人:cwcyxy
发表时间:2003-06-20 17:37:34

--------------------------------------------------------------------------------

发信人:jiangbo123
发表时间:2003-06-20 17:38:27

--------------------------------------------------------------------------------

你的type 卡读写搞定了吗?

发信人:yzrui 发表时间:2003-06-20 17:45:55

--------------------------------------------------------------------------------

写FIFO的操作可以在中断函数外完成

发信人:xlfdan
发表时间:2003-06-20 19:36:09

--------------------------------------------------------------------------------

发信人:cwcyxy
发表时间:2003-06-20 19:47:25

--------------------------------------------------------------------------------

于去年搞定了,用的是rc531,

只是无市场,没有深入研究,今天看了看。

发信人:xlfdan
发表时间:2003-06-20 21:51:46

--------------------------------------------------------------------------------

发信人:hyeena
发表时间:2003-06-23 11:58:07

--------------------------------------------------------------------------------

我在这253了!!!!!!!!!!

发信人:try it
发表时间:2003-06-23 12:07:48

--------------------------------------------------------------------------------

我用89c52对CM200模块进行读写,在发request命令后我读stacon的值却总是为零,

好象模块根本就没有工作一样.我是完全按照data_sheet上做的,真不知是什么原因.请指

教!!!!!

发信人:chaplinxu
发表时间:2003-06-23 17:16:02

--------------------------------------------------------------------------------

发信人:chaplinxu
发表时间:2003-06-23 17:16:51

--------------------------------------------------------------------------------

发信人:竹香子 发表时间:2003-06-25 10:47:54

--------------------------------------------------------------------------------

同上。

发信人:竹香子 发表时间:2003-06-25 14:31:55

--------------------------------------------------------------------------------

同上。

发信人:竹香子 发表时间:2003-06-25 14:34:38

--------------------------------------------------------------------------------

jiangbo123:

您好!

问题:

在对卡进行安全认证时,当被认证的密码与卡的密码不对时,该M500PiccAuth()也返回true,而真正的密码功能在下面进一步的操作中才起作用,如:read(),write()中:即密码对时可读写,错时不可读写。

//函数调用如下:

unsigned char
xdata i;

unsigned long
xdata lCardID;

unsigned char
xdata key[6]={0x11,0xff,0xff,0xff,0xff,0xff};

for(i=0; i<8; i )

if (MIF_Poll(0x52))

if (MIF_AntiColl(0, &lCardID))

if (MIF_SelectCard(&lCardID))

if(M500PiccAuth(PICC_AUTHENT1A,(unsigned char*)&lCardID,key,4)) //上面函数参数:keyAB,*snr,*key,block

if (Read(0x04, 4, cCarddata))



问题:

1、当密码key[0..5]与卡密码相等时,M500PiccAuth()返回成功:true,读块函数Read()成功;

2、当密码key[0..5]与卡密码不等时,M500PiccAuth()也返回成功:true,但Read()失败。

也即M500PiccAuth()老返回true,可能有问题。根据我的追踪测试发现,问题出在最终调用的函数M500PiccAuthState( )上,其总返回true,即标记的???处。

对照philips的源码,我们实在看不出来,故向您求教。由于客户比较急,故请您能在百忙中抽点时间帮我们看看。谢谢!

//以下几个函数是我们根据贵方提供的代码改的,基本未变,只是将返回改为bool型。

bool M500PiccAuth(unsigned
char keyAB, // KEYA or KEYB

unsigned
char *snr, // 4 bytes card serial number

unsigned
char *key, // 密码指针,6B

unsigned
char block) // 卡block:0--63

{

bool bOK=false;

unsigned char keycoded[12];

M500HostcodeKey(key,keycoded);

bOK = M500PiccAuthKey(keyAB,

snr,

keycoded,

block);

return bOK;

}

bool M500PiccAuthKey(unsigned
char auth_mode,

unsigned
char *snr,

unsigned
char *keys,

unsigned
char block)

{

bool bOK=false;

unsigned char i;

RegControl |= 0x01; // empty FIFO buffer

for(i=0;i<12;i )

gcSenddata = keys; // write 12 bytes of the key

gcSendLength = 12;

if( PcdSingleResponseCmd(PCD_LOADKEY) ) // write load command

bOK = M500PiccAuthState(auth_mode,snr,block); // execute authentication

return bOK;

}

bool M500PiccAuthState(
unsigned char auth_mode,

unsigned
char *snr,

unsigned
char block)

{

bool bOK=false;

if(RegErrorFlag != 0) // read error flags of the previous key load

return false;

else

{

gcSenddata[0] = auth_mode; // write authentication command

gcSenddata[1] = block; // write block number
for authentication

gcSenddata[2] = snr[0];

gcSenddata[3] = snr[1];

gcSenddata[4] = snr[2];

gcSenddata[5] = snr[3];

gcSendLength = 6;

if(PcdSingleResponseCmd(PCD_AUTHENT1))

{

if(RegSecondaryStatus & 0x07) // Check RxLastbits
for error

bOK = false;

else

{

gcSendLength = 0; //无参数

if(PcdSingleResponseCmd(PCD_AUTHENT2))

{

if(RegControl & 0x08 ) // cmd success:authent2

bOK = true; //????????????

else

bOK = false;

}

}

}

}

return bOK;

}

void M500HostcodeKey(unsigned
char *uncoded,

unsigned
char *coded)

{

unsigned char i;

unsigned char ln = 0; // low nibble

unsigned char hn = 0; // high nibble

for (i=0; i<6; i )

{

ln = uncoded & 0x0F;

hn = uncoded >> 4;

coded[i * 2 1] = (~ln << 4) | ln;

coded[i * 2 ] = (~hn << 4) | hn;

}

}

发信人:hyeena
发表时间:2003-06-25 15:30:44

--------------------------------------------------------------------------------

会不会是你做完第一次正确的Authentication之后没有把位Crypto1On清零啊?

发信人:jiangbo123
发表时间:2003-06-26 10:07:29

--------------------------------------------------------------------------------

你的M500PiccAuthState函数我已经仔细看过,应该没有什么问题,仔细看看你的PcdSingleResponseCmd函数和中断服务程序的处理过程,是不是那里出现问题了。

发信人:竹香子 发表时间:2003-06-26 11:23:40

--------------------------------------------------------------------------------

其实我仔细对比过philips给的源码里的那两个函数,一样的。不过我倒相信你以前说的话,philips给的源码里是有很多bug,只能靠自己用肉眼去find,在调试中我就碰到过多次。

先行谢谢了,我先去找找看。

发信人:竹香子 发表时间:2003-06-26 11:27:09

--------------------------------------------------------------------------------

其实我仔细对比过philips给的源码里的那两个函数,一样的。不过我倒相信你以前说的话,philips给的源码里是有很多bug,只能靠自己用肉眼去find,在调试中我就碰到过多次。

先行谢谢了,我先去找找看

发信人:jiangbo123
发表时间:2003-06-26 12:41:22

--------------------------------------------------------------------------------

很多用rc500开发读写器同仁经常会遇到rc500损坏的情况,其实很多情况并不是rc500真正的物理损坏,特别是调试读写eeprom函数的时候,由于程序的bug或者误操作造成了eeprom中第1块和第2块数据的改写,该处保存了rc500启动寄存器初始化数据,这些初始化数据是生产的时候写进去的默认值,每次rc500复位之后会自动根据该初始化数据初始化片内的相关寄存器(初始化的寄存器地址从0x10~0x2f),一旦eeprom中保存的默认值被错误改写,就会导致寄存器初始化了错误的数值,从而导致rc500不能正常工作。这种情况的损坏其实是很容易修复的,因为datasheet中提供了所有的初始化数据,只需将这些数据重新写回相应的地址就ok了,采用这种办法我修复好几块rc500芯片。如果你的rc500出现问题不要想都不想就扔掉哟,希望这些提示对大家有用!!

发信人:jiangbo123
发表时间:2003-06-26 12:46:30

--------------------------------------------------------------------------------

char cRepairChip()

{

unsigned char RevBuffer[40],status;

//数据分两次写入,每次写一块,即16字节

//其实分两次写入的话可以将buf定义小一点,懒得改了。

RevBuffer[0]=0x10;//写eeprom的起始地址

RevBuffer[1]=0x10;//写入数据的长度,前16字节

//根据datasheet的寄存器初始化数值

RevBuffer[2]=0x00;

RevBuffer[3]=0x58;

RevBuffer[4]=0x3f;

RevBuffer[5]=0x3f;

RevBuffer[6]=0x19;

RevBuffer[7]=0x13;

RevBuffer[8]=0x00;

RevBuffer[9]=0x00;

RevBuffer[10]=0x00;

RevBuffer[11]=0x73;

RevBuffer[12]=0x08;

RevBuffer[13]=0xad;

RevBuffer[14]=0xff;

RevBuffer[15]=0x00;

RevBuffer[16]=0x41;

RevBuffer[17]=0x00;

RevBuffer[18]=0x20;//第二次写入的eeprom首址

RevBuffer[19]=0x10;//写入的长度,16字节

//根据datasheet的寄存器初始化数值

RevBuffer[20]=0x00;

RevBuffer[21]=0x06;

RevBuffer[22]=0x03;

RevBuffer[23]=0x63;

RevBuffer[24]=0x63;

RevBuffer[25]=0x00;

RevBuffer[26]=0x00;

RevBuffer[27]=0x00;

RevBuffer[28]=0x00;

RevBuffer[29]=0x08;

RevBuffer[30]=0x07;

RevBuffer[31]=0x06;

RevBuffer[32]=0x0a;

RevBuffer[33]=0x02;

RevBuffer[34]=0x00;

RevBuffer[35]=0x00;

status=PcdWriteE2(RevBuffer[0],RevBuffer[1],&RevBuffer[2]);

if(status)

return error;

status=PcdWriteE2(RevBuffer[18],RevBuffer[19],&RevBuffer[20]);

return status;

}

发信人:竹香子 发表时间:2003-06-26 13:46:46

--------------------------------------------------------------------------------

请问RC500的认证到底与哪几个寄存器有关?如何配置?对比philips给的源码实在看不出问题在哪里。

发信人:ljj730
发表时间:2003-06-26 14:29:38

--------------------------------------------------------------------------------

谁有红外线传感器方面的资料

发信人:xlfdan
发表时间:2003-06-26 20:06:24

--------------------------------------------------------------------------------

发信人:xlfdan
发表时间:2003-06-26 20:11:45

--------------------------------------------------------------------------------

发信人:yaohang
发表时间:2003-06-27 09:49:32

--------------------------------------------------------------------------------

很多人对RC500损伤感到头痛,其实99。99%的RC500损伤是软故障,通过初始化程序或自编一段小程序完全可以恢复。另外,请注意RC500中的RFU只读寄存器实际是可变的,会影响CRC校验,通过程序完全可以恢复此类软损伤。我公司去年一个项目,平均每天有两位数RC500损坏,很是头痛,今年初经过软件修补升级后,再没有出现过RC500损伤的情况。

发信人:jiangbo123
发表时间:2003-06-27 12:30:38

--------------------------------------------------------------------------------

如果是寄存器的值变了,如何软件修复呢?也是将初始值重新写入?

发信人:siguo1
发表时间:2003-06-28 15:21:35

--------------------------------------------------------------------------------

发信人:jiangbo123
发表时间:2003-06-28 16:43:21

--------------------------------------------------------------------------------

rc531的demo程序更乱。呵呵。

发信人:yaohang
发表时间:2003-06-30 08:45:00

--------------------------------------------------------------------------------

如果寄存器的值发生变化,可以反推算CRC校验值,利用可改写的寄存器反填数值,使CRC校验恢复正常。具体怎样操作,我不太清楚,我不是实际搞开发的。

发信人:knightls
发表时间:2003-06-30 16:28:55

--------------------------------------------------------------------------------

你有什么联系方式吗?我的QQ:45713091,大家讨论一下

发信人:jiangbo123
发表时间:2003-07-03 10:05:59

--------------------------------------------------------------------------------

包括对eeprom的读写都可以限制嘛。呵呵,还是不明白。

发信人:qgque 发表时间:2003-07-04 10:06:01

--------------------------------------------------------------------------------

RC500RST = 0; // clear reset pin

delay_1ms(25); // wait
for 25ms

RC500RST = 1; // reset RC500

delay_50us(50); // wait
for 2.5ms

RC500RST = 0; // clear reset pin

谁讲讲为什么RC500的复位要按照上面这样写?我看RC500的datasheet,在P82,有下面这样的一段话:

The Hard Power down Phase is active during the following
cases:

. Power On Reset caused by power up at pin DVDD

(active while DVDD is below the digital reset threshold)

. Power On Reset caused by power up at pin AVDD

(active while AVDD is below the digital reset threshold)

. A HIGH level on pin RSTPD

(active while pin RSTPD is HIGH)

也就是说RSTPD=1后,RC500进入Hard Power down Phase,Reset Phase 自动跟在Hard Power
down Phase后,是不是RSTPD还是保持高电平?

另外在P96有下面这样一段话:

The StartUp-Command runs the Reset and Initialisation Phase.It
does not need or return any
data.It can hot be activated by the u-Processor but is started
automatically after one of the following events:

. Power On Reset caused by power up at Pin DVDD

. Power On Reset caused by power up at Pin AVDD

. Negative Edge at Pin RSTPD

也就是说在RSTPD需要出现下降沿才执行Reset Phase 和Initialisation Phase,好像和上面有点冲突阿?

现在我的问题是屏蔽掉RSTPD=0;这两条语句,键盘操作就正确,不屏蔽掉这两条语句,键盘就没有相应,另外需要说明的是:

1. RSTPD接在MCU的P3.3;

2. 屏蔽掉RSTPD=0;这两条语句后就不能读卡写卡了。

发信人:jiangbo123
发表时间:2003-07-04 14:28:46

--------------------------------------------------------------------------------

rc500的rst引脚平时应该是低电平,复位是下降沿还是高电平其实对于写程序来说没有什么太大区别。你屏蔽掉RSTPD=0,使得RSTPD始终为高电平,rc500当然不能正常工作,所以不能读写卡了。我认为文档没有冲突。导致rc500和8255冲突的原因可能是你硬件问题,或者是软件上在他们的地址计算不对造成的。

发信人:irenehan
发表时间:2003-07-04 16:41:57

--------------------------------------------------------------------------------

请问对于TYPE A卡来说,RC500的程序可以直接用在RC531上吗?

我看531的 SingleResponseIsr(void)程序的HiAlertIRQ or RxIRQ Handling

部分有个do while语句,500中没有,可是有这条语句使得接收到的字节数

总是不对而发生错误。

我用531对CPU卡进行操作时,读回的数据经常在0时出错变成FF,可能是什么原因呢?

谢谢

发信人:irenehan
发表时间:2003-07-04 16:52:00

--------------------------------------------------------------------------------

能给点建议吗?请问怎样把RC500的各个子程序封装成LINUX下的驱动程序呀?

比较困惑,只知道应该把CONFIG放在INIT中,其他的就不知道了,请给点指点

谢谢

发信人:rfcard
发表时间:2003-07-04 16:59:45

--------------------------------------------------------------------------------

发信人:tomgroup
发表时间:2003-07-04 18:39:34

--------------------------------------------------------------------------------

读写器程序主循环里一直查卡,但放上两张或多张卡后,RC500不再识卡,测量后,TX1和TX2脚都有输出,程序也没有死 ,这是为什么,都快急死了?大虾救命啊!!

发信人:jiangbo123
发表时间:2003-07-05 12:07:44

--------------------------------------------------------------------------------

做成linux驱动,可以将其他所有的卡操作函数都放到IOCTRL函数里面。

发信人:jiangbo123
发表时间:2003-07-05 12:09:51

--------------------------------------------------------------------------------

如果你要用到系统中断,好象必须写成驱动的形式。当然你也可以采用查询方式。

发信人:jiangbo123
发表时间:2003-07-05 12:12:32

--------------------------------------------------------------------------------

有多张卡时,应该是可以轮流寻到每张卡,但是注意有时候,多张卡之间不能离得太近,比如你将多张卡贴在一起,那么可能导致通讯相互干扰,导致寻卡失败。

发信人:tomgroup
发表时间:2003-07-05 18:46:30

--------------------------------------------------------------------------------

我同意你的观点,但在实际应用中要出现这样可就不好办了。我现在怀疑防冲突的处理中出了问题,能不能将你的防冲突函数发给我?

还有我发现卡与卡的差异很大,之间的干扰也不尽相同。您说的轮流选卡,我还没理解。您用到卡挂起了吗?Reqstd或ReqAll请求主要是用在哪些方面的应用?急盼复!我的Email:xys12@sohu.com,谢谢先。

发信人:whf_27
发表时间:2003-07-06 21:14:16

--------------------------------------------------------------------------------

我有一个问题:

就是Mifare1卡的卡号是4个字节的,才4294967296个卡号,因为用了这么多年了,会不会有重复的可能?有什么办法没有?

发信人:irenehan
发表时间:2003-07-07 10:26:25

--------------------------------------------------------------------------------

可是IOTRL能返回字符串吗?他不是只能返回整数,代表操作是否成功吗?

那对于ANTICOLL操作时需要返回卡系列好的呀,这怎么处理呢?

发信人:jiangbo123
发表时间:2003-07-07 10:49:20

--------------------------------------------------------------------------------

static int
rc500_open(struct inode *inode,
struct file *file)

{

if(rc500_is_open){

return -EBUSY;

}

rc500_is_open=1;

MfConfig();

return 0;

}

static void rc500_close(struct inode *inode,
struct file *file)

{

rc500_is_open=0;

}

static int
rc500_write(struct inode *inode,
struct file *file, unsigned
char *buf, int count)

{

if(MfWrite(rc500_offset,buf) != 0)

{

return -EINVAL;

}

return 16;

}

static int
rc500_read(struct inode *inode,
struct file *file, unsigned
char *buf, int count)

{

static long reg;

if(MfRead(rc500_offset,buf)!=0){

return -EINVAL;

}

}

static int
rc500_ioctl(struct inode *inode,
struct file *file, unsigned
int cmd,unsigned
long arg)

{

char status;

switch(cmd)

{

case GETDEVSNR:

status = GetDevSnr((unsigned
char*)arg);

break;

case MFREQUEST:

status = MfRequest((unsigned
char*)arg,(unsigned
char*)(arg 2));

break;

case MFAUTHENE2:

status = MfAuthenE2(*(unsigned
char*)arg,*(unsigned
char*)(arg 1),*(unsigned
char*)(arg 2));

break;

case MFLOADKEYE2:

status = MfLoadKeyE2(*(unsigned
char*)arg,*(unsigned
char*)(arg 1),(unsigned
char*)(arg 2));

break;

case MFAUTHENKEY:

status = MfAuthenKey(*(unsigned
char*)arg,(unsigned
char*)(arg 1),(unsigned
char*)(arg 5),*(unsigned
char*)(arg 11));

break;

case READE2:

status = ReadE2(*(unsigned
char*)arg,*(unsigned
char*)(arg 1),(unsigned
char*)(arg 2));

break;

case WRITEE2:

status = WriteE2(*(unsigned
char*)arg,*(unsigned
char*)(arg 1),(unsigned
char*)(arg 2));

break;

default:

status = -EINVAL;

}

}

发信人:jiangbo123
发表时间:2003-07-07 17:20:04

--------------------------------------------------------------------------------

这样只要卡不离开天线区域,用reqstd就不能寻到该卡了,而用reqall则可以继续寻到该卡。比如公交卡上扣了一次钱必须使用idle,不然,卡上的钱迅速被扣光。

发信人:lixu 发表时间:2003-07-07 21:44:01

--------------------------------------------------------------------------------

各位:

请问mcm sb600的wkomp引脚如何使用?

发信人:lixu 发表时间:2003-07-07 21:46:39

--------------------------------------------------------------------------------

MCM SB600的WKOMP引脚如何使用?

发信人:lixu 发表时间:2003-07-07 22:08:23

--------------------------------------------------------------------------------

MCM SB600 CS与NCS 如何区别?MODE,USEALE引脚如何使用?

软件编程中查询模式与中断模式如何区别?如何使用?

发信人:zhoujj
发表时间:2003-07-09 08:30:13

--------------------------------------------------------------------------------

我支持你,还有片选啊什么的,我都是直接接地,^_^

免得烦

发信人:irenehan
发表时间:2003-07-09 12:50:57

--------------------------------------------------------------------------------

太谢谢你了,真的给了我很大启发。

我还有个问题,就是我在接收数据时,当数据是0时经常出错

但子程序返回的status还是0,也就是说结果正确,不知道是

不是rc531接收的数据没错,而传给处理器时出错呢?这个程

序在51单片机上好用,我现在用的是arm7。你用过龙珠,不

知道你遇到过我说的这种情况吗?谢谢。

发信人:hyeena
发表时间:2003-07-09 16:07:22

--------------------------------------------------------------------------------

我用的是查询方式,不是用中断的!

发信人:jiangbo123
发表时间:2003-07-10 09:25:09

--------------------------------------------------------------------------------

用在什么cpu上其实都差不多,只是底层的读写寄存器的函数改改而已,可以检查以下是不是arm的速度过快,是不是需要适当增加延时。

to hyeena:

当然可以用查询方式。

发信人:hyeena
发表时间:2003-07-10 16:26:29

--------------------------------------------------------------------------------

我发现有好多变量像nBytesReceived都是在中断里设置的,如果用查询方式的话,应该怎么做?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: