📄 tda8007_routines.c
字号:
/*
Routine_C2.c
realease 1.0
19/06/2001
*/
int_TDA8007() interrupt 0 using 1
{
bit save_P15;
unsigned char save_AUXR;
unsigned char pdata *ptr;
unsigned char pdata *ptr_TOR1;
unsigned char ch;
save_P15 = P15;
save_AUXR = AUXR;
AUXR = AUXR | EXT_XRAM;
P15 = 0;
ptr = USR;
ptr_TOR1 = TOR1;
user_byte = *ptr;
if(user_byte & 0xFE) // not TBE/RBF
{
if(TO1 == 1) // TO1 used for 19200 etus count or 108 etus count
{
nb_loop1--;
if((nb_loop1 == 0))
{
alarm = card_selected;
deactive = 1;
card_comm_error = MAX_DURATION_ATR;
}
goto end_IT;
}
if(TO3 == 1)
{
flag_timer3 = 1; // timer 2 + 3 SW is used for 108 etus count
if(flag_ATR) // timer 2 + 3 SW is used for 9600 etus count during ATR
{
flag_timer3 = 0;
flag_ATR = 0;
alarm = card_selected;
deactive = 1;
card_comm_error = ATR_MUTE;
}
else if (flag_APDU)
{
alarm = card_selected; // timer 1 + 2 + 3 start bit is used for 9600 etus count
card_comm_error = TIME_OUT;
}
goto end_IT;
}
if( OVF == 1)
{
alarm = card_selected;
card_comm_error = UART_OVERFLOW; //overflow
}
if( EARLY == 1)
{ //Early ATR
alarm = card_selected;
card_comm_error = EARLY_ANSWER;
}
if( FER == 1) // FER or OVR
{
alarm = card_selected;
card_comm_error = FRAMING_ERROR; //framing error
}
if(PE == 1)
{
ptr = UCR1;
ch = *ptr; //reading UCR1
//Parity error in T=0
if((ch & 0x10) == 0)
{
alarm = card_selected;
if((ch & 0x08) == 0) // Receive mode
{ // using parity error counter
card_comm_error = RX_ERR_PARITY;
}
else // Transmit mode
{
// using automatic retransmission
card_comm_error = TX_ERR_PARITY;
}
}
else
{
parity_error_T1 = 1;
if(flag_ATR)
{
alarm = card_selected;
deactive = 1;
card_comm_error = ATR_ERR_PARITY;
}
}
}
}
ptr = HSR;
user_byte = *ptr;
if( PRT2 == 1)
{
card_comm_error = CARD2_DEACTIVATED;
alarm = 0x02;
}
if( PRT1 == 1)
{
card_comm_error = CARD1_DEACTIVATED;
alarm = 0x01;
}
if( PRL1 == 1)
{
alarm = 0x01;
card_config[0].card_move = 1;
}
if( PRL2 == 1)
{
alarm = 0x02;
card_config[1].card_move = 1;
}
if( (SUPL == 1) )
{
alarm = card_selected;
card_comm_error = SUPERVISOR_ACTIVATED;
}
if( PTL == 1)
{
alarm = card_selected;
card_comm_error = TEMPERATURE_ALARM;
}
end_IT:
ptr = MSR;
user_byte = *ptr;
AUXR = save_AUXR;
P15 = save_P15;
}
/**********************************************************/
unsigned char rcv_card(unsigned int nb,unsigned int ptr)
{
uchar pdata *pointer_urr=URR;
uchar pdata *pointer_msr=MSR;
uchar pdata *ptr_toc=TOC;
uchar pdata *ptr_tor2=TOR2;
uchar pdata *ptr_tor3=TOR3;
uchar ch;
if(nb==0)
return(OK);
if(protocol_type==0)
{
if(ptr + nb > (buffer_length+2))
{
card_comm_error = BUFFER_SIZE_TOO_SHORT;
stop_timers();
return(!OK);
}
}
if(End_ATR && (nb_last_bytes_ATR == 1))
{
End_ATR = 0;
if(emv && RestartTimerSoft)
{ // setting bit EATR
*ptr_toc = 0xE5; // on C1 version EATR stop only Timer 1
} // setting bit EATR to stop all timers on the
RestartTimerSoft = 0; // 12th etu of the next start bit
}
for(;nb > 0;nb--,ptr++)
{
AUXR = EXT_XRAM;
P15 = 0;
do // wait for one byte in FIFO
{
user_byte = *pointer_msr;
if(alarm == card_selected) // only if alarm appends on card selected
{
*ptr_toc = 0; // stop timers
P15 = 1;
AUXR = INT_XRAM;
return(!OK);
}
}while(FE);
if(end_APDU&&(nb==1)) // stop timers at the end of APDU in T=1
{
*ptr_toc = 0;
end_APDU = 0;
}
if( flag_ATR && RestartTimerSoft)
{
if(emv )
{
#ifdef FAST_UC
// delay is expected between two consecutive write in the TOC register
*ptr_toc = 0x05; // timer2+3 stop
do
{
*ptr_tor3 = 0x25;
*ptr_tor2 = 0x80;
}while(!(*pointer_msr & 0x10));
*ptr_toc = 0x65; // restart timer 2+3 SW
#else
*ptr_toc = 0x05; // timer2+3 stop
*ptr_tor3 = 0x25;
*ptr_tor2 = 0x80;
*ptr_toc = 0x65; // restart timer 2+3 SW
#endif
}
else
{
#ifdef FAST_UC
// delay is expected between two consecutive write in the TOC register
*ptr_toc = 0x00; // timer1 and 2+3 stop
do
{
*ptr_tor3 = 0x25;
*ptr_tor2 = 0x80;
}while(!(*pointer_msr & 0x10));
*ptr_toc = 0x61; // restart timer 2+3 SW
#else
*ptr_toc = 0x00; // timer1 and 2+3 stop
*ptr_tor3 = 0x25;
*ptr_tor2 = 0x80;
*ptr_toc = 0x61; // restart timer 2+3 SW
#endif
} // counter 1 stop, restart timer 2+3 SW
nb_last_bytes_ATR--;
}
ch = *pointer_urr;
if(End_ATR && (nb_last_bytes_ATR == 1))
{
End_ATR = 0;
if(emv && RestartTimerSoft)
{ // setting bit EATR
*ptr_toc = 0xE5; // with C1 version EATR stop only Timer 1
} // with C2 version EATR stop all timer if at least
RestartTimerSoft = 0; // one timer is running in start bit mode
}
AUXR = INT_XRAM;
P15 = 1;
checksum = checksum ^ ch;
#ifndef UCRD
if(ptr>buffer_length-1)
{
pointer_idata = exceed_buff + (ptr-buffer_length);
exceed_bytes = ptr - (buffer_length-1);
*pointer_idata = ch;
}
else
{
exceed_bytes = 0;
data_exch_buff[ptr] = ch;
}
#else
data_exch_buff[ptr] = ch;
#endif
}
return(OK);
}
/*******************************************************************/
uchar send_to_card(unsigned int nb, unsigned int ptr)
{
if(asser_mode_flag == 0)
{
return(send_bytes_to_card(nb,ptr));
}
else // asserved mode, only T=0 protocol
{
if(send_bytes_to_card(1,ptr) != OK)
{
return(!OK);
}
ptr++;
nb--;
while(nb >= 0)
{
while( 1 )
{
if(nb == 0)
return(OK);
if( rcv_card(1,0x00) != OK) // receive SW1 or ~INS or NULL byte
return(!OK);
if(data_exch_buff[0x00] != 0x60) // turn in while(1) loop until PCB=!0x60
break;
}
if(data_exch_buff[0x00] == ins) // now not asserved mode
asser_mode_flag = 0;
if( (data_exch_buff[0x00] != ~ins) && (data_exch_buff[0x00] != ins) )
{
if( rcv_card(1,0x01) !=OK) //receive SW2
return(!OK);
asser_mode_flag = 0;
write_bit(TXRX,0); //set tda8007 in high impedance
return(OK);
}
wait_BGT(); // Using BGT feature in T=0
// so that the minimum time before
// sending bytes to the card will be 16 etus
if(asser_mode_flag == 0) // back to not asserved mode during transmission
{
return(send_bytes_to_card(nb,ptr));
}
else
{ // allways in asserved mode
if(send_bytes_to_card(1,ptr) != OK)
{
return(!OK);
}
nb--;
ptr++;
}
}
}
}
/****************************************************************/
bit send_bytes_to_card(unsigned int nb,unsigned int ptr) //par polling
{
uchar pdata *ptr_utr=UTR;
uchar pdata *ptr_msr=MSR;
uchar pdata *ptr_ucr1=UCR1;
uchar pdata *ptr_tor1=TOR1;
uchar pdata *ptr_tor2=TOR2;
uchar pdata *ptr_tor3=TOR3;
uchar ch, TX_mode;
bit Get_One_Byte = 1;
unsigned int Tx_pointer = ptr;
unsigned int Tx_counter = nb;
#ifndef UCRD
if(Tx_pointer<buffer_length) // buffer_length needs to be 256
ch = data_exch_buff[Tx_pointer++];
else
ch = exceed_buff[Tx_pointer++];
#else
ch = data_exch_buff[Tx_pointer++];
#endif
write_bit(TXRX,1);
AUXR = EXT_XRAM;
P15 = 0;
do{
if (Tx_counter==1)
{
*ptr_ucr1 |= 0x04; //LCT = 1 returning uart at the last byte
}
*ptr_utr = ch; //transmit one byte
do {
if(Get_One_Byte)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -