📄 tda8007.c
字号:
// Set smartcard clock to 1/1 crystal
tda_writeregister(CCR,0x00);
#elif ((CRYSTAL_FREQUENCY_8007 >= 2000000L) && (CRYSTAL_FREQUENCY_8007 <= 10000000L))
// Set smartcard clock to 1/2 crystal
tda_writeregister(CCR,0x01);
#elif ((CRYSTAL_FREQUENCY_8007 >= 4000000L) && (CRYSTAL_FREQUENCY_8007 <= 20000000L))
// Set smartcard clock to 1/4 crystal
tda_writeregister(CCR,0x02);
#elif ((CRYSTAL_FREQUENCY_8007 >= 8000000L) && (CRYSTAL_FREQUENCY_8007 <= 40000000L))
// Set smartcard clock to 1/8 crystal
tda_writeregister(CCR,0x03);
#else
// Set smartcard clock to 1/2 internal oscillator (about 1.44MHz)
// NOTE: Can only change CCR.2 when shifting to internal oscillator
tda_writeregister(CCR,0x01);
tda_writeregister(CCR,0x05);
// Wait for internal oscillator to engage (check the MSR.CLKSW bit on page 18)
if ( DEBUG > 2 )
printk("Waiting for Clock to switch\n");
do
{
val = tda_readregister(MSR);
}while (!(val & MSR_CLKSW_MASK));
#endif
printk("Preparing to Apply Power1\n");
// Set the power supply voltage
val = tda_readregister(PCR);
// Clear 1.8V and 3V bits
tda_writeregister(PCR,val & ~(PCR_3V_5V_MASK|PCR_1V8_MASK));
switch(voltage)
{
case POWERUP_5V:
// Do nothing
break;
case POWERUP_3V:
val = tda_readregister(PCR);
// Set 3V bit
tda_writeregister(PCR,val | PCR_3V_5V_MASK);
break;
case POWERUP_1p8V:
val = tda_readregister(PCR);
// Set 1.8V bit
tda_writeregister(PCR,val | PCR_1V8_MASK);
break;
default:
return ERR_POWERUP_VOLTAGE_INVALID;
break;
}
// Apply reset
val = tda_readregister(PCR);
tda_writeregister(PCR,val & ~PCR_RSTIN_MASK);
printk("Preparing to Apply Power1\n");
val = tda_readregister(HSR);//clear HSR
do
{
//Power the card, RST low, C4 and C8 high
val = tda_readregister(PCR);
tda_writeregister(PCR,val | (PCR_C8_MASK|PCR_C4_MASK|PCR_START_MASK));
//tda_writeregister(PCR,val | PCR_START_MASK);
val = tda_readregister(HSR);
if (val & (HSR_PRTL2_MASK|HSR_PRTL1_MASK|HSR_PRL2_MASK|HSR_PRL1_MASK|HSR_PTL_MASK))
{
#if DEBUG > 0
printk("Power problem detected 0x%2x\n",val);
#endif
tda_powerdown();
return ERR_POWERUP_INTERRUPTED;
}
val = tda_readregister(PCR);
}while (!(val & PCR_START_MASK));
#if DEBUG > 1
printk("Power is on\n");
#endif
// Call common getATR routine
return 0;
//return tda_ATRsequence(mode);
}
/*************************************************************************
功能:
参数:
Read a byte from the UART or timeout after BWT (T=1), CWT (T=1) or WWT (T=0).
Not tested
返回值:-1: error
0: OK
**************************************************************************/
static signed char readByte(uchar *temp)
{
u8 val;
uint timeout;
//printk("tda_readregister(UCR1) = 0x%x\n",tda_readregister(UCR1));
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
//while(!(tda_readregister(USR) & USR_TBE_RBF_MASK))
while(!(tda_readregister(MSR) & MSR_TBE_RBF_MASK))
{
val = tda_readregister(USR);
if (val & USR_PE_MASK)
{
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -