📄 ecrcard.c
字号:
continue;
}
else
{
if(lout==le) lout=0; //没有读取到数据
in_buf[0]=lout;
in_buf[3]=bw.byte.Hi;
in_buf[4]=bw.byte.Lo;
EA=1;
return 0;
}
}//SW1,SW2--0x60-0x9f
if(r_w_byte==ins) //命令完成,可以传输数据块
{
if(lc) //写数据
{
do
{
error=send_cpu_byte(*out);
if(error) //奇偶错
{
EA=1;
return error;
}
out++;
}while(--lc);
continue;
}
else if(le) //读本记录的有效存储数据
{
do
{
error=rece_cpu_byte(); //读数据
if(error)
{
EA=1;
return error;
}
delay_half_etu();
*in=r_w_byte;
in++;
}while(--le);
continue;
}
continue;
}//SW1==ins
r_w_byte=~r_w_byte;
if(r_w_byte==ins) //命令完成,只可以传输单字节数据
{
if(lc) //写数据
{
error=send_cpu_byte(*out);
if(error) //奇偶错
{
EA=1;
return error;
}
out++;
--lc;
continue;
}
else if(le) //读1字节本记录的有效存储数据
{
error=rece_cpu_byte(); //读数据
if(error)
{
EA=1;
return error;
}
delay_half_etu();
*in=r_w_byte;
in++;
--le;
continue;
}
continue;
}//SW1==/ins
ins++;
if(r_w_byte==ins) //卡类型错
{
EA=1;
return CARDER;
}//SW1==/(ins+1)
r_w_byte=~r_w_byte;
if(r_w_byte==ins) //卡类型错
{
EA=1;
return CARDER;
}//SW1==ins+1;
else //通信出错
{
EA=1;
return TRANER;
}
}//while(1)
}
/*SAM CARD*/
uchar rece_sam_byte(void)
{
uchar i,j=4,m;
uint k;
do
{
m=sam_d; //等待起始位960 X SAM_D X SAM_TC2
do
{
i=sam_tc2;
do
{
k=9600;
SAM_CARD_IO=1;
do //10us
{
if(!SAM_CARD_IO) break;
}while(--k);
if(!SAM_CARD_IO) break;
}while(--i);
if(!SAM_CARD_IO) break;
}while(--m);
if(!m) return TIMEO; //超时出错
delay_half_etu();
i=8;
do //读出8数据位
{
delay_etu();
if(sam_t)
{
r_w_byte=r_w_byte>>1;
HBIT=SAM_CARD_IO;
_nop_();
}
else
{
r_w_byte=r_w_byte<<1;
LBIT=SAM_CARD_IO;
_nop_();
_nop_();
_nop_();
}
}while(--i);
delay_etu(); //接收奇偶校验码
if(!sam_t) r_w_byte=~r_w_byte;
ACC=r_w_byte;
PSW1=P;
F0=SAM_CARD_IO;
delay_half_etu();
if(PSW1)
{
if(F0) return 0;
}
else
{
if(!F0) return 0;
}
delay_half_etu();
SAM_CARD_IO=0; //10.5 * etu发送错误信号
delay_etu();
delay_etu();
SAM_CARD_IO=1;
}while(--j);
return PARERR;
}
uchar send_sam_byte(uchar send_data)
{
uchar i,j=4;
do
{
SAM_CARD_IO=1;
delay_etu(); //字符间隔时间
delay_etu();
delay_etu();
delay_etu();
SAM_CARD_IO=1;
if(!SAM_CARD_IO) return PARERR;
if(sam_tc1&&(sam_tc1!=0xff))
{
i=sam_tc1;
do
{
delay_half_etu();
delay_half_etu();
}while(--i);
}
SAM_CARD_IO=0; //发送起始位
r_w_byte=send_data;
if(!sam_t) r_w_byte=~r_w_byte;
i=8;
do
{
delay_etu();
if(sam_t)
{
SAM_CARD_IO=LBIT;
r_w_byte=r_w_byte>>1;
_nop_();
}
else
{
SAM_CARD_IO=HBIT;
r_w_byte=r_w_byte<<1;
_nop_();
_nop_();
_nop_();
_nop_();
}
}while(--i);
delay_etu();
ACC=send_data;
_nop_();
_nop_();
SAM_CARD_IO=P; //发送奇偶校验位
delay_etu();
r_w_byte=5;
while(--r_w_byte);
SAM_CARD_IO=1; //检测错误信号
delay_etu();
r_w_byte=5;
while(--r_w_byte);
if(SAM_CARD_IO) return 0; //11 * etu
delay_half_etu();
}while(--j);
return PARERR;
}
uint atr_samcard(uchar *buf)
{
uchar xdata i,temp,atr_len,error,cpu_tck=0,ti=0;
uchar xdata *p;
uint j=10000;
UNST bw;
atr_len=0;
p=buf;
bw.word=0;
sam_ta1=0x11,sam_d=1,sam_tc1=0,sam_tc2=10;
EA=0;
samcard_vcc(1);
SAM_CARD_RST=0;
do //等待起始位
{
if(!SAM_CARD_IO) break;
}while(--j);
SAM_CARD_RST=1;
sam_t=1; //以正向协议传输
if(rece_sam_byte()) //TS
{
EA=1;
bw.byte.Lo=CPUCARDER; //非CPU卡
return bw.word;
}
if(r_w_byte==0x03) //反向传输
{
sam_t=0;
r_w_byte=0x3f;
}
else if(r_w_byte!=0x3b) //正向传输
{
EA=1;
bw.byte.Lo=CPUCARDER; //非CPU卡
return bw.word;
}
*p=r_w_byte;
p++;
atr_len++;
error=rece_sam_byte(); //接收T0
if(error)
{
bw.byte.Lo=error;
EA=1;
return bw.word;
}
*p=r_w_byte;
p++;
atr_len++;
bw.byte.Hi=r_w_byte&0x0f; //保存历史字节数据长度
if((r_w_byte&0x0f)>32) //历史字节数据超长出错
{
EA=1;
bw.byte.Lo=RECEOV;
return bw.word;
}
atr_sam1:
temp=r_w_byte>>4;
i=4;
do //Td1...Tdi
{
if(temp&0x01)
{
error=rece_sam_byte();
if(error)
{
bw.byte.Lo=error;
EA=1;
return bw.word;
}
*p=r_w_byte;
p++;
atr_len++;
if(atr_len==32) //数据超长出错
{
EA=1;
bw.byte.Lo=RECEOV;
return bw.word;
}
if(i==4) //TAi
{
if(!ti) sam_ta1=r_w_byte; //TA1决定接收字符间最大时间
else if(ti==1) cpu_tck=1; //TA2...N表示有TCK校验
}
else if(i==2) //TCi
{
if(!ti) sam_tc1=r_w_byte; //TC1决定发送字符间最小时间
else if(ti==1) sam_tc2=r_w_byte; //TC2决定接收字符间最大时间
}
else if(i==1) //TDi---是否有TCK
{
if(r_w_byte&0x0f) cpu_tck=1; //TDi表示有TCK校验
ti++;
goto atr_sam1;
}
}
temp=temp>>1;
}while(--i);
if(bw.byte.Hi) //有历史数据
{
i=bw.byte.Hi;
bw.byte.Hi+=atr_len;
do //读出历史字节:T1...Tk
{
error=rece_sam_byte();
if(error)
{
bw.byte.Lo=error;
EA=1;
return bw.word;
}
*p=r_w_byte;
p++;
atr_len++;
if(atr_len==32) //数据超长出错
{
EA=1;
bw.byte.Lo=RECEOV;
return bw.word;
}
}while(--i);
}
else bw.byte.Hi=atr_len;
if(cpu_tck) //有TCK校验
{
error=rece_sam_byte(); //读出TCK校验值
if(error)
{
bw.byte.Lo=error;
EA=1;
return bw.word;
}
*p=r_w_byte;
p++;
atr_len++;
temp=0; //TCK校验
for(i=1;i<atr_len;i++) temp^=buf[i];
if(temp) //异或校验出错
{
EA=1;
bw.byte.Lo=XORERR;
return bw.word;
}
}
if(!sam_tc2) sam_tc2=10;
switch(sam_ta1&0x0f)
{
case 1:
sam_d=1;
break;
case 2:
sam_d=2;
break;
case 3:
sam_d=4;
break;
case 4:
sam_d=8;
break;
case 5:
sam_d=16;
break;
case 6:
sam_d=32;
break;
case 8:
sam_d=12;
break;
case 9:
sam_d=20;
break;
default:
break;
}
EA=1;
return bw.word;
}
uchar Sam_Apdu(uchar xdata *out_buf,uchar xdata *in_buf)
{
uchar data ins;
uchar i,lc,le,lout,error,send_flag=0;
uchar xdata buf[10];
uchar xdata *out,*in;
uchar xdata **pp;
UNST bw;
EA=0;
le=0;
lc=out_buf[4];
for(i=0;i<5;i++) buf[i]=out_buf[i];
if(!lc) //只读数据
{
le=out_buf[7];
buf[4]=le;
}
lout=le;
ins=buf[1];
pp=(uchar *)&out_buf[5];
out=*pp;
pp=(uchar *)&in_buf[1];
in=*pp;
bw.word=0;
while(1)
{
if(!send_flag) //发送命令
{
send_flag=1;
for(i=0;i<5;i++)
{
error=send_sam_byte(buf[i]);
if(error) //奇偶错
{
EA=1;
return error;
}
}
}
error=rece_sam_byte(); //读ACK1
if(error)
{
EA=1;
return error;
}
bw.byte.Hi=r_w_byte;
if(r_w_byte==0x60) continue; //CPU卡忙
if(((r_w_byte&0xf0)==0x60)||((r_w_byte&0xf0)==0x90)) //此时SW1=ACK1
{
error=rece_sam_byte(); //读SW2
if(error)
{
EA=1;
return error;
}
bw.byte.Lo=r_w_byte;
send_flag=0;
if(bw.byte.Hi==0x61) //lc,le同时有效
{//读取数据长度与文件实际长度不匹配,重发
buf[0]=0;
buf[1]=0xc0;
buf[2]=0;
buf[3]=0;
buf[4]=r_w_byte;
le=r_w_byte;
lout=le;
ins=buf[1];
continue;
}
else if(bw.byte.Hi==0x6c) //没有lc时有效
{//读取剩余数据
buf[4]=r_w_byte;
le=r_w_byte;
lout=le;
continue;
}
else
{
if(lout==le) lout=0; //没有读取到数据
in_buf[0]=lout;
in_buf[3]=bw.byte.Hi;
in_buf[4]=bw.byte.Lo;
EA=1;
return 0;
}
}//SW1,SW2--0x60-0x9f
if(r_w_byte==ins) //命令完成,可以传输数据块
{
if(lc) //写数据
{
do
{
error=send_sam_byte(*out);
if(error) //奇偶错
{
EA=1;
return error;
}
out++;
}while(--lc);
continue;
}
else if(le) //读本记录的有效存储数据
{
do
{
error=rece_sam_byte(); //读数据
if(error)
{
EA=1;
return error;
}
delay_half_etu();
*in=r_w_byte;
in++;
}while(--le);
continue;
}
continue;
}//SW1==ins
r_w_byte=~r_w_byte;
if(r_w_byte==ins) //命令完成,只可以传输单字节数据
{
if(lc) //写数据
{
error=send_sam_byte(*out);
if(error) //奇偶错
{
EA=1;
return error;
}
out++;
--lc;
continue;
}
else if(le) //读1字节本记录的有效存储数据
{
error=rece_sam_byte(); //读数据
if(error)
{
EA=1;
return error;
}
delay_half_etu();
*in=r_w_byte;
in++;
--le;
continue;
}
continue;
}//SW1==/ins
ins++;
if(r_w_byte==ins) //卡类型错
{
EA=1;
return CARDER;
}//SW1==/(ins+1)
r_w_byte=~r_w_byte;
if(r_w_byte==ins) //卡类型错
{
EA=1;
return CARDER;
}//SW1==ins+1;
else //通信出错
{
EA=1;
return TRANER;
}
}//while(1)
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -