📄 tda8007.c
字号:
printk("parity error\n");
return PARITY1_ERR;
}
if (val & (USR_TOL3_MASK|USR_TOL2_MASK|USR_TOL1_MASK))
{
printk("timeout error 0x%2x\n",val);
return ERR_RECEIVE_TIMEOUT;
}
//printk("UCR1 = 0x%x",tda_readregister(UCR1));
}
// Read and store byte
val = tda_readregister(URR);
*temp = val;
if (TMode[currentSlot] == 0)
timeout = WWT[currentSlot]; // Use WWT for T=0
else
timeout = CWT[currentSlot]; // Use CWT for T=1
// Set up timer for 24 bit timer, start immediately
tda_writeregister(TOC,0x00);
tda_writeregister(TOR3,timeout >> 16);
tda_writeregister(TOR2,timeout >> 8);
tda_writeregister(TOR1,timeout);
tda_writeregister(TOC,0x68);
delay_us(5);
return 0;
}
/*************************************************************************
功能:
参数:
Write a byte and leave the 8007 in transmit mode
返回值:-1: error
0: OK
**************************************************************************/
int writeByte(uint onebyte)
{
volatile u8 val;
val = tda_readregister(UCR1);
// set T bit
tda_writeregister(UCR1,val | UCR1_T_R_MASK);
tda_writeregister(UTR,onebyte);
// wait for byte to go out
delay_us(20);
do{
val = tda_readregister(USR);
if(val & USR_PE_MASK)return PARITY2_ERR;
}while (!(val & USR_TBE_RBF_MASK));
return 0;
//
//while (!(tda_readregister(MSR) & MSR_TBE_RBF_MASK));
}
/*************************************************************************
功能:
参数:
Write a byte and put the 8007 in receive mode
返回值:-1: error
0: OK
**************************************************************************/
int writeLastByte(uint onebyte)
{
volatile u8 val;
uint timeout;
timeout = WWT[currentSlot]; // Use WWT for T=0
// Set up timer for 24 bit timer, edge trigger start
tda_writeregister(TOC,0x00);
tda_writeregister(TOR3,timeout >> 16);
tda_writeregister(TOR2,timeout >> 8);
tda_writeregister(TOR1,timeout);
tda_writeregister(TOC,0x7C);
val = tda_readregister(UCR1);
// set LCT and T bit
tda_writeregister(UCR1,val | (UCR1_T_R_MASK|UCR1_LCT_MASK));
tda_writeregister(UTR,onebyte);
delay_us(20);
// wait for byte to go out
do{
val = tda_readregister(USR);
if(val & USR_PE_MASK)return PARITY2_ERR;
}while (!(val & USR_TBE_RBF_MASK));
return 0;//2007-10-22 15:11:05
}
/*************************************************************************
功能:
参数:
Send a message using T=1 protocol
返回值:-1: error
0: OK
**************************************************************************/
static int TDA_iccard_comm( unsigned char * send_buf,
int send_len,
unsigned char *rec_buf,
int *rec_len)
{
signed char rlt;
int m;
int n = 0;
int i = 0;
unsigned char tmp_ins[5];
unsigned char *ptr;
unsigned char INS;
unsigned char first = 1;
unsigned char ins_flag = 0;
int s3c_adpu_Lc,s3c_adpu_Le;
int flag_60 = 0;
uchar tmp[2];
uchar ins_1 = 0;
place_err = 0;
*rec_len = 0;
//memset(temp_60, 0, 255);
if (send_len < 4)
{
place_err = 20;
return ADPU_ERR;
}
if (send_len == 4)
{
tmp[0] = *(send_buf);
tmp[1] = *(send_buf + 1);
tmp[2] = *(send_buf + 2);
tmp[3] = *(send_buf + 3);
tmp[4] = 0;
s3c_adpu_Le = tmp[4];
s3c_adpu_Lc = -1;
INS = tmp[1];
ptr = tmp; //CLS
}
else if (send_len == 5)
{
s3c_adpu_Le = *(send_buf + 4);
s3c_adpu_Lc = -1;
INS = *(send_buf + 1);
ptr = send_buf; //CLS
}
else
{
s3c_adpu_Lc = *(send_buf + 4);
if (send_len == s3c_adpu_Lc + 5) s3c_adpu_Le = -1;
else if (send_len == s3c_adpu_Lc + 5 + 1)
s3c_adpu_Le = *( send_buf + send_len - 1);
else
{
place_err = 21;
return ADPU_ERR;
}
INS = * (send_buf + 1);
ptr = send_buf; //CLS
}
if ( ( s3c_adpu_Lc == -1 ) && (s3c_adpu_Le == -1) )
return ADPU_ERR;
if ( ( s3c_adpu_Lc >= 255 ) || (s3c_adpu_Le >= 255) )
return ADPU_ERR;
if ( ( s3c_adpu_Lc == 0 ) )
return ADPU_ERR;
//save_flags(flags); cli();
rlt = iccard_write(ptr, 5); //发送5字节的命令头
if(rlt < 0)
{
place_err = 30;
printk("rlt = %d\n",rlt);
return rlt; // time out
}
ptr = rec_buf; //接受缓冲首地址
if ( s3c_adpu_Lc != -1 )
{ //写卡, Lc存在且不为0
while(1)
{ // receive one byte INS
rlt = readByte(tmp);
if (rlt < 0)
{
*rec_len = 0;
//restore_flags(flags);
printk("rlt = %d\n",rlt);
place_err = 1;
return rlt; // time out err or parity err
}
else *ptr = tmp[0];
if (!( *ptr == 0x60) ) //0x60 等待;
break;
}
ptr = send_buf + 5; //数据段首址
if ( ( rec_buf[0] == INS )||( rec_buf[0] == (INS^0x01) ) )
{
//delay_one_etu();//2007-3-5 14:36
//delay_one_etu();//2007-3-5 14:39针对华旭卡
rlt = iccard_write(ptr, s3c_adpu_Lc); //发送Lc个字节
if(rlt < 0)
{
place_err = 31;
printk("rlt = %d\n",rlt);
return rlt; // time out
}
ptr = rec_buf; //收的数据
if ( s3c_adpu_Le == -1 )
{ // Le not exist
while(1)
{
rlt = readByte(tmp);
if (rlt < 0) {
*rec_len = 0;
//restore_flags(flags);
place_err = 24;
printk("rlt = %d\n",rlt);
printk("n = %d\n",n);
for(m = 0; m < n + 1; m++)
printk("ptr[%d] = 0x%2x\n",m,ptr[m]);
return rlt; // time out err or parity err
}
else *ptr = tmp[0];
n++;
if ( !((*ptr == 0x60)&&(first == 1)) )
{ //0x60 等待;
first = 0;
ptr++;
(*rec_len)++;
if ( *rec_len >= 2 )
{
//restore_flags(flags);
printk("s3c_adpu_Le4 = %d\n",s3c_adpu_Le);
return 0;
}
}
}
}
else
{ // Le exist
while(1)
{
rlt = readByte(tmp);
if (rlt < 0)
{
*rec_len = 0;
//restore_flags(flags);
printk("rlt = %d\n",rlt);
place_err = 25;
return rlt; // time out err or parity err
}
else *ptr = tmp[0];
if((*ptr == INS)||(*ptr == (INS^0x01))) break;
}
i = 2;
while(i--)
{
rlt = readByte(tmp);
if ( rlt < 0 )
{
//restore_flags(flags);
*rec_len = 0;
return rlt; // parity err
}
else *ptr = tmp[0];
ptr++;
(*rec_len)++;
}
//restore_flags(flags);
return 0;
}
}
else if( ( rec_buf[0] == (INS^0xff) )||( rec_buf[0] == (INS^0xfe) ) )
{
//delay_one_etu();
//delay_one_etu(); // rev one byte return at 10.5 etu, if change to send data, delay at least 1.5 etu
i = s3c_adpu_Lc - 1;
while(i--)
{
rlt = iccard_write(ptr, 1); //发送1字节
if(rlt < 0)
{
place_err = 32;
printk("rlt = %d\n",rlt);
return rlt; // time out
}
rlt = readByte(tmp);
if ( rlt < 0 )
{
*rec_len = 0;
//restore_flags(flags);
printk("rlt = %d\n",rlt);
place_err = 23;
return rlt; // parity err
}
tmp_ins[0] = tmp[0];
if((tmp_ins[0] == (INS^0xff))||(tmp_ins[0] == (INS^0xfe)))
ptr++;
//delay_one_etu();
//delay_one_etu();
}//end i--
rlt = iccard_write(ptr, 1); //发送1字节
if(rlt < 0)
{
place_err = 33;
printk("rlt = %d\n",rlt);
return rlt; // time out
}
i = 2;
ptr = rec_buf;
while(i--)
{
rlt = readByte(tmp);
if ( rlt < 0 )
{
*rec_len = 0;
return rlt; // parity err
}
else *ptr = tmp[0];
ptr++;
(*rec_len)++;
}
//restore_flags(flags);
return 0;
}
else
{ // Sw1+ SW2, 收SW2
ptr++; //留下上一个收到的字节,是SW1
(*rec_len)++;
rlt = readByte(tmp);
if (rlt<0)
{
*rec_len = 0;
//restore_flags(flags);
printk("rlt = %d\n",rlt);
place_err = 10;
return rlt; // time out err or parity err
}
else *ptr = tmp[0];
ptr++;
(*rec_len)++;
//restore_flags(flags);
return 0;
}
}
else
{ //读卡,Lc 不存在(-1)
while(1)
{ // receive one byte INS
rlt = readByte(tmp);
if (rlt < 0)
{
*rec_len = 0;
//restore_flags(flags);
printk("rlt = %d\n",rlt);
place_err = 11;
return rlt; // time out err or parity err
}
else *ptr = tmp[0]; ins_1 = tmp[0];
if ( !(*ptr == 0x60) )
{ //0x60 等待;
break;
}
}
if ( ( rec_buf[0] == INS )||( rec_buf[0] == (INS^0x01) ) )
{
if ( s3c_adpu_Le == 0 )
{
while(1)
{
rlt = readByte(tmp);
if ( rlt < 0 )
{
*rec_len = 0;
//restore_flags(flags);
printk("rlt = %d\n",rlt);
place_err = 12;
return rlt; // parity err
}
else *ptr = tmp[0];
ptr++;
(*rec_len)++;
if ( *rec_len >= 256 )
{
//restore_flags(flags);
printk("s3c_adpu_Le3 = %d\n",s3c_adpu_Le);
return 0;
}
}
}
else
{ // Le !=0 && !=-1 (因为Le和Lc不能同时为-1)
//first = 1; //重新等待过程字节
while(1)
{
rlt = readByte(tmp);
if (rlt < 0)
{
//restore_flags(flags);
printk("rlt = %d\n",rlt);
for(m = 0; m < *rec_len; m++)
printk("rec_buf[%d] = 0x%2x\n",m,rec_buf[m]);
for(m = 0; m < flag_60; m++)
printk("temp_60[%d] = 0x%2x\n",m,temp_60[m]);
place_err = 13;
//printk("%d jiaoyanerr = %d\n partity = %d\n flag_60 = %d\n",
//card_selected,jiaoyanerr,partity,flag_60);
*rec_len = 0;
return rlt; // time out err or parity err
}
*ptr = tmp[0];
temp_60[flag_60++] = *ptr;
if(*rec_len >= s3c_adpu_Le)
{
if(*ptr == 0x60) continue;
}
ptr++;
(*rec_len)++;
if ( *rec_len >= s3c_adpu_Le + 2 )
{
//restore_flags(flags);
printk("s3c_adpu_Le2 = %d\n",s3c_adpu_Le);
return 0;//2007-3-29 15:24 add
}
}
}
}
else if( ( rec_buf[0] == (INS^0xff) )||( rec_buf[0] == (INS^0xfe) ) )
{
ins_flag = 0;
first = 1;
while(1)
{
rlt = readByte(tmp);
if ( rlt < 0 )
{
*rec_len = 0;
//restore_flags(flags);
printk("rlt = %d\n",rlt);
place_err = 14;
return rlt; // parity err
}
else *ptr = tmp[0];
if(*rec_len >= s3c_adpu_Le )
{
if(*ptr == 0x60) continue;
}
if ( !((*ptr == 0x60)&&(first == 1)) )
{ //0x60 等待;
first = 0;
if(ins_flag)
{
ins_flag = 0;
}
else
{
if( *rec_len < s3c_adpu_Le-1) ins_flag = 1;
ptr++;
(*rec_len)++;
if ( *rec_len >= s3c_adpu_Le + 2)
{
printk("s3c_adpu_Le1 = %d\n",s3c_adpu_Le);
return 0;
} // +1??
}
}//end if
}//end while
}
else
{ // Sw1+ SW2, 收SW2
ptr++; //留下上一个收到的字节,是SW1
(*rec_len)++;
rlt = readByte(tmp);
if (rlt<0)
{
*rec_len = 0;
//restore_flags(flags);
printk("rlt = %d\n",rlt);
place_err = 15;
return rlt; // time out err or parity err
}
else *ptr = tmp[0];
ptr++;
(*rec_len)++;
printk("s3c_adpu_Le0 = %d INS = %x \n",s3c_adpu_Le,ins_1);
//restore_flags(flags);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -