📄 tda8007.c
字号:
}
}
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);
return 0;
}
}
}
/*************************************************************************
功能:热复位
参数:
返回值:-1: error
0: OK
**************************************************************************/
int tda_warmreset(uchar mode, unsigned char *rec_buf,
int * rec_len,
int cardname)
{
uchar val;
// Check for power status
val = tda_readregister(PCR);
if (!(val & PCR_START_MASK))
return ERR_POWERUP_VOLTAGE_INVALID;
// Apply reset
val = tda_readregister(PCR);
tda_writeregister(PCR,val & ~PCR_RSTIN_MASK);
// Call common getATR routine
return tda_ATRsequence(mode, rec_buf, rec_len);
}
/*************************************************************************
功能:复位应答
参数:
返回值:-1: error
0: OK
**************************************************************************/
static int tda_ATRsequence(uchar mode, uchar *rec_buf, int *rec_len)
{
volatile u8 val;
volatile u16 count;
uchar USRval;
uchar index;
uchar historicalBytes = 0;
uchar expectedCharacters = 0;
uchar etucount = 0;
uchar interfaceIteration = 1;
uchar done = 0;
uchar check = 0;
uchar i = 0;
// Default to T=0 mode
uchar T = 0;
uint curByte;
//printk("tda_ATRsequence L1125\n");
clearATRStruct(&lastATR[currentSlot]);
// Reset the UART
val = tda_readregister(CSR);
tda_writeregister(CSR,val & ~CSR_nRIU_MASK);
// Remove UART reset
val = tda_readregister(CSR);
tda_writeregister(CSR,val | CSR_nRIU_MASK);
// Set FIFO to 1 byte; parity Error Count 3 byte
tda_writeregister(FCR,0x00);
tda_writeregister(FCR,FCR_PEC0_MASK | FCR_PEC1_MASK);
// Set divisor
tda_writeregister(PDR,12);
// Set prescaler
tda_writeregister(UCR2,0x00);
// Enable auto convention
val = tda_readregister(UCR2);
tda_writeregister(UCR2,val & ~UCR2_nAUTOCONV_MASK);
// Set SS bit
tda_writeregister(UCR1,UCR1_SS_MASK);
// Wait 40000 to 45000 cycles to release reset
//printk("wait counters for reset\n");
tda_writeregister(TOC, 0x00);
delay_us(5);
tda_writeregister(TOR3, 0x00);
delay_us(5);
tda_writeregister(TOR2, 0x6C);
delay_us(5);
tda_writeregister(TOR1, 0x00);
delay_us(5);
tda_writeregister(TOC, 0x61);
//delay_us(5);
count = 0;
printk("TOC = %x\n",tda_readregister(TOC));
do
{
if(++count > 5000)
{
printk("Time 2 not end!\n");
break;
}
val = tda_readregister(USR);
}while (!(val & USR_TOL3_MASK));
printk("Set up counters for reset\n");
if (mode == POWERUP_ISO)
{
// Wait up to 40000 cycles for ATR to start
tda_writeregister(TOC,0x00);
delay_us(5);
tda_writeregister(TOR3,0x00);
delay_us(5);
tda_writeregister(TOR2,0x78);
delay_us(5);
tda_writeregister(TOR1,0x00);
delay_us(5);
tda_writeregister(TOC,0x61);
}
else // power up EMV
{
// Wait up to 40000 cycles for ATR to start and 19200 etu counter after first byte
tda_writeregister(TOC,0x00);
tda_writeregister(TOR3,0x00);
tda_writeregister(TOR2,0x78);
tda_writeregister(TOR1,0xC0);
tda_writeregister(TOC,0x65);
}
//printk("Release reset\n");
val = tda_readregister(PCR);
tda_writeregister(PCR,val | PCR_RSTIN_MASK);
while (1)
{
val = tda_readregister(MSR);
// If we see the first character come in, break.
if (val & MSR_TBE_RBF_MASK)break;
val = tda_readregister(USR);
if (val & (USR_PE_MASK|USR_FER_MASK|USR_OVR_MASK|USR_EA_MASK))
{
tda_powerdown();
if(val & USR_PE_MASK)
{
printk("ATR error: PARITY1_ERR\n");
return PARITY1_ERR;
}
else
{
printk("ATR error: USR=0x%2x\n", val);
return ERR_POWERUP_ATR_INVALID;
}
}
if (val & USR_TOL3_MASK)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -