RC531调试CPU卡出现问题。

xiaoyanzijjjjj 2015-02-08 05:09:49
大家好,最近在调试CPU卡消费。
CPU卡---是已经初始话好的卡,我现在只需要做消费。消费需要用到的PSAM卡也已经调试完毕,具体的消费指令流程也知道了。
读卡芯片--RC531芯片。现在可以实现对M1卡进行减值,写值操作。应该来说我的读卡硬件是没问题。
控制器用的是C8051F系列的一款单片机。
现在的问题是,用我的读卡电路可以寻到卡,选中CPU卡片,然后我发送了RATS命令,卡片也有回复。当发送一条选MF命令时,提示我出错。
RATS命令:
MSndBuffer[0] = 0xE0; //
MSndBuffer[1] = 0x10;
MInfo.nBytesToSend = 2; //
status = M500PcdCmd(PCD_TRANSCEIVE,MSndBuffer,MRcvBuffer,&MInfo);
RATS回复:
status =0;----代表成功
收到的数据:12 78 B3 B1 02 00 81 4D 22 08 86 60 12 22 26 20 00 01
发送选择MF命令:
MSndBuffer[0]=0x0a;
MSndBuffer[1]=0x01;
MSndBuffer[2]=0x00;
MSndBuffer[3]=0xA4;
MSndBuffer[4]=0x00;
MSndBuffer[5]=0x00;
MSndBuffer[6]=0x02;
MSndBuffer[7]=0x3f;
MSndBuffer[8]=0x01;

MInfo.nBytesToSend = 9; //
status = M500PcdCmd(PCD_TRANSCEIVE,MSndBuffer,MRcvBuffer,&MInfo);
此时:status=0xff------无卡的意思。
下面是选择MF子函数
unsigned char select_mf(unsigned char *buf)
{
char idata status = MI_OK;

M500PcdSetTmo(3);
WriteIO(RegChannelRedundancy,0x0F);
ClearBitMask(RegControl,0x08);
ResetInfo(MInfo); //
MSndBuffer[0]=0x0a;
MSndBuffer[1]=0x01;
MSndBuffer[2]=0x00;
MSndBuffer[3]=0xA4;
MSndBuffer[4]=0x00;
MSndBuffer[5]=0x00;
MSndBuffer[6]=0x02;
MSndBuffer[7]=0x3f;
MSndBuffer[8]=0x01;
MInfo.nBytesToSend = 9; //
status = M500PcdCmd(PCD_TRANSCEIVE,MSndBuffer,MRcvBuffer,&MInfo);
if (status)
{
*buf = 0;
}
else
{
if (MInfo.nBytesReceived == 0)
{
*buf = 0;
status = MI_EMPTY;
}
else
{
status = MI_OK;
memcpy(buf,MRcvBuffer,MInfo.nBytesReceived);
}
}
return status;
}
M500PCBcommand 用的RC531原厂库函数
//////////////////////////////////////////////////////////////////////
// W R I T E A P C D C O M M A N D
///////////////////////////////////////////////////////////////////////
char M500PcdCmd(unsigned char cmd,
volatile unsigned char* send,
volatile unsigned char* rcv,
volatile MfCmdInfo *info)
{
char data status = MI_OK;
char data tmpStatus ;
unsigned char data lastBits;

unsigned char data irqEn = 0x00;
unsigned char data waitFor = 0x00;
unsigned char data timerCtl = 0x00;


WriteIO(RegInterruptEn,0x7F); // disable all interrupts
WriteIO(RegInterruptRq,0x7F); // reset interrupt requests
WriteIO(RegCommand,PCD_IDLE); // terminate probably running command

FlushFIFO(); // flush FIFO buffer

// save info structures to module pointers
MpIsrInfo = info;
MpIsrOut = send;
MpIsrIn = rcv;

info->irqSource = 0x0; // reset interrupt flags
// depending on the command code, appropriate interrupts are enabled (irqEn)
// and the commit interrupt is choosen (waitFor).
switch(cmd)
{
case PCD_IDLE: // nothing else required
irqEn = 0x00;
waitFor = 0x00;
break;
case PCD_WRITEE2: // LoAlert and TxIRq
irqEn = 0x11;
waitFor = 0x10;
break;
case PCD_READE2: // HiAlert, LoAlert and IdleIRq
irqEn = 0x07;
waitFor = 0x04;
break;
case PCD_LOADCONFIG: // IdleIRq
case PCD_LOADKEYE2: // IdleIRq
case PCD_AUTHENT1: // IdleIRq
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_CALCCRC: // LoAlert and TxIRq
irqEn = 0x11;
waitFor = 0x10;
break;
case PCD_AUTHENT2: // IdleIRq
irqEn = 0x04;
waitFor = 0x04;
break;
case PCD_RECEIVE: // HiAlert and IdleIRq
info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4);
irqEn = 0x06;
waitFor = 0x04;
break;
case PCD_LOADKEY: // IdleIRq
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_TRANSMIT: // LoAlert and IdleIRq
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_TRANSCEIVE: // TxIrq, RxIrq, IdleIRq and LoAlert
info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4);
irqEn = 0x3D;
waitFor = 0x04;
break;
default:
status = MI_UNKNOWN_COMMAND;
}
if (status == MI_OK)
{
// Initialize uC Timer for global Timeout management
irqEn |= 0x20; // always enable timout irq
waitFor |= 0x20; // always wait for timeout

//start_timeout(4000); // initialise and start guard timer for reader
// 50us resolution, 200ms

WriteIO(RegInterruptEn,irqEn | 0x80); //necessary interrupts are enabled
WriteIO(RegCommand,cmd); //start command

// wait for commmand completion
// a command is completed, if the corresponding interrupt occurs
// or a timeout is signaled

//while ((!(MpIsrInfo->irqSource & waitFor) || T2IR)); // wait for cmd completion or timeout
while (!(MpIsrInfo->irqSource & waitFor) );

WriteIO(RegInterruptEn,0x7F); // disable all interrupts
WriteIO(RegInterruptRq,0x7F); // clear all interrupt requests
SetBitMask(RegControl,0x04); // stop timer now

//stop_timeout(); // stop timeout for reader
WriteIO(RegCommand,PCD_IDLE); // reset command register


if (!(MpIsrInfo->irqSource & waitFor)) // reader has not terminated
{ // timer 2 expired
status = MI_ACCESSTIMEOUT;
}
else
status = MpIsrInfo->status; // set status

if (status == MI_OK) // no timeout error occured
{
if (tmpStatus = (ReadIO(RegErrorFlag) & 0x17)) // error occured
{
if (tmpStatus & 0x01) // collision detected
{
info->collPos = ReadIO(RegCollpos); // read collision position
status = MI_COLLERR;
}
else
{
info->collPos = 0;
if (tmpStatus & 0x02) // parity error
{
status = MI_PARITYERR;
}
}
if (tmpStatus & 0x04) // framing error
{
status = MI_FRAMINGERR;
}
if (tmpStatus & 0x10) // FIFO overflow
{
FlushFIFO();
status = MI_OVFLERR;
}
if (tmpStatus & 0x08) //CRC error
{
status = MI_CRCERR;
}
if (status == MI_OK)
status = MI_NY_IMPLEMENTED;
// key error occures always, because of
// missing crypto 1 keys loaded
}
// if the last command was TRANSCEIVE, the number of
// received bits must be calculated - even if an error occured
if (cmd == PCD_TRANSCEIVE)
{
// number of bits in the last byte
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; // reset interface variables for ISR
MpIsrOut = 0;
MpIsrIn = 0;
return status;
}
...全文
1246 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
lw996953944 2017-04-17
  • 打赏
  • 举报
回复
你好,我现在寻卡没有问题,返回正确,但是RATS却错误了。有没有资料啊,网上说的也没太弄明白。
chaoyue0726 2017-03-16
  • 打赏
  • 举报
回复
获取mf 是 3f 00 不是3f 01 指令不对
  • 打赏
  • 举报
回复
不懂你这个芯片的命令,你好好看协议吧,出错是否有返回错误信息呢? 直接找技术支持吧。
xiaoyanzijjjjj 2015-02-08
  • 打赏
  • 举报
回复
自己 顶一下,求帮助啊

3,846

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 无线
社区管理员
  • 无线
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧