⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iccard.b.c

📁 嵌入式系统上用的SMARTCARD的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
			//EVOC_select_usr();
		}
		else return NO_SELECTED_CARD_ERR;	
		
		count=0;
		while ( CARD_RX ) 
		{
			count++;
			if (count>=timeout) return TIMEROUT_ERR;
		}
	
		delay_half_etu();		//0.5etu
		
		for( i=0;i<8;i++)
		{		// receive 8 bits data
			delay_one_etu();	//1.5etu - 8.5etu
			if ( card_logic_mode == POSITIVE_LOGIC )
			{
				if ( CARD_RX )
					*revdata = (*revdata>>1)|0x80;
				else    *revdata = (*revdata>>1);
			}
			else
			{
				if ( CARD_RX )
					*revdata = (*revdata<<1)|0x01;
				else    *revdata = (*revdata<<1);
			}
			
		}
		
		delay_one_etu();	//9.5etu

		if ( CARD_RX )
		{	//receive parity bit
			parity_bit = 1;
			if (rev_TS==TS_BIT)
			{
				delay_one_etu();	//10.5 etu // TS receive ok
				return 0;
			}
		}
		else
		{
			parity_bit = 0;
			if (rev_TS==TS_BIT){
				goto REV_TS_ERR;// TS receive err
			}
		}

		if ( parity_bit == (     (  *revdata         >> 7)
					^( (*revdata & 0x40) >> 6)
					^( (*revdata & 0x20) >> 5)
					^( (*revdata & 0x10) >> 4)
					^( (*revdata & 0x08) >> 3)
				        ^( (*revdata & 0x04) >> 2)
				        ^( (*revdata & 0x02) >> 1)
				        ^( (*revdata & 0x01)     ) )    ) 
		{		
			delay_one_etu();	//10.5 etu 
			return 0;
		}
REV_TS_ERR:
		//parity err
		delay_one_etu();		//10.5 etu 
		
		CARD_TX_CLR;

		delay_one_etu();		//11.5 etu 
		delay_half_etu();		//12 etu
		
		CARD_TX_SET;	
		
		delay_half_etu();		//12.5 etu

		re_rev_times++;
	}
	return 	PARITY1_ERR;
}
//*******************************************************
//*******************************************************
static int iccard_reset(	unsigned char * rec_buf,
			int  * rec_len)

{

	int rlt,i,j;
	unsigned char * ptr;
	unsigned char revT0TD;
	unsigned char TCK_exist;
	unsigned char TDi_exist;
	unsigned char parity_TCK;
	unsigned int * card_logic_mode;
	
	*rec_len = 0;
	*rec_buf = 0;
			
	if (card_selected==SAMCARD) 
	{
		card_logic_mode = &logic_mode_sam;
		EVOC_sam_card_pwr_on();
		EVOC_select_sam();	
		delay_cycle(1000);		
		EVOC_sam_set_card_rst();
		delay_1200_cycle();
		EVOC_sam_clr_card_rst();
	}
	else if(card_selected==USRCARD)
	{
		card_logic_mode = &logic_mode_usr;
		EVOC_usr_card_pwr_on();
		EVOC_select_usr();
		delay_cycle(1000);
		
		EVOC_usr_set_card_rst();
		delay_1200_cycle();
		EVOC_usr_clr_card_rst();
	}
	else return NO_SELECTED_CARD_ERR;	
		
	ptr = rec_buf;
	*card_logic_mode = POSITIVE_LOGIC;

	rlt = EVOC_rev_one_byte(ptr,REV_TS_TIMEOUT_CYCLE,TS_BIT);		//receive TS
	if (rlt<0) {
		*rec_len = 0;
		return rlt;		// time out err or parity err		
	}
	if  ( *ptr == 0x3b ) {
		*card_logic_mode = POSITIVE_LOGIC;
	}
	else if  ( *ptr == 0x3f ){
		*card_logic_mode = NEGATIVE_LOGIC;
	}
	else {
		printk("%s: *ptr = %s\n",ptr);
		*rec_len = 0;		
		return CARD_ERR;
	}

	if ( (++ptr) >= (ptr+ATR_MAX_LEN ) ) {
		*rec_len = 0;			
		return ATR_LEN_ERR;
	}
	rlt = EVOC_rev_one_byte(ptr,TIMEOUT_MAX_CYCLE,NOT_TS_BIT);		//receive T0
	if (rlt<0) {
		*rec_len = 0;
		return rlt;		// time out err or parity err		
	}
	revT0TD = *ptr;
	
	i=0;
	j=0;
	while (i<4)
	{
		if ((revT0TD>>i)&0x10) 
		{
			if ( (++ptr) >= (ptr+ATR_MAX_LEN ) ) {
				*rec_len = 0;			
				return ATR_LEN_ERR;
			}
			rlt = EVOC_rev_one_byte(ptr,TIMEOUT_MAX_CYCLE,NOT_TS_BIT);		//receive TA(i),TB(i),TC(i),TD(i)
			if (rlt<0) 
			{
				*rec_len = 0;
				return rlt;		// time out err or parity err		
			}
			i++;
			if (i==3&&j==0)
			{	
				if (card_selected==SAMCARD) 
					protect_time_sam = *ptr;
				else if(card_selected==USRCARD)
					protect_time_usr = *ptr;
				else return NO_SELECTED_CARD_ERR;
			}
			if (i==3&&j==1){	
				TC2_WI = *ptr;
			}	
			if (i==4)
			{
				TDi_exist=1;
				revT0TD = *ptr;
				i=0;
				j++;
			}
		}
		else i++;
	}	
	if (rec_buf[1]&0x80)
	{	//TD exist
		if (revT0TD&0x0f)  TCK_exist=1;
		else TCK_exist=0;
	}
	else
	{		//TD not exist, T=0, TCK not exist
		TCK_exist=0;
	}

	i=0;
	while ( i<(rec_buf[1]&0x0f) )
	{
		if ( (++ptr) >= (ptr+ATR_MAX_LEN ) ) 
		{
			*rec_len = 0;			
			return ATR_LEN_ERR;
		}
		rlt = EVOC_rev_one_byte(ptr,TIMEOUT_MAX_CYCLE,NOT_TS_BIT);		//receive T1,...,TK
		if (rlt<0) 
		{
			*rec_len = 0;
			return rlt;		// time out err or parity err		
		}
		i++;
	}

	if (TCK_exist)
	{
		if ( (++ptr) >= (ptr+ATR_MAX_LEN ) ) 
		{
			*rec_len = 0;			
			return ATR_LEN_ERR;
		}
		rlt = EVOC_rev_one_byte(ptr,TIMEOUT_MAX_CYCLE,NOT_TS_BIT);		//receive TCK
		
		parity_TCK =0;
		for (i=1;i<(ptr-rec_buf+1);i++)	
		{		//xor parity from T0 to TCK
			parity_TCK ^= rec_buf[i];
		}
		if (parity_TCK != 0) 
		{
			*rec_len = 0;			
			return ATR_XOR_ERR;
		}
	}
	*rec_len = (ptr-rec_buf+1);
	return 0;
}
//*******************************************************
//*******************************************************
static int EVOC_iccard_reset(	unsigned char * rec_buf,
			int  * rec_len,
			int cardname	)
{
	if (cardname==SAMCARD) 
	{
		cardname = card_selected;
		card_selected = SAMCARD;
		samcard_err = iccard_reset(rec_buf,rec_len);
		card_selected  = cardname;
		if (samcard_err<0) 
		{
			EVOC_sam_card_release();
			return samcard_err;
		}
	}
	else if(cardname==USRCARD)
	{
		cardname = card_selected;
		card_selected = USRCARD;
		usrcard_err = iccard_reset(rec_buf,rec_len);
		card_selected  = cardname;
		if (usrcard_err<0) 
		{
			EVOC_usr_card_release();
			return	usrcard_err;
		}
	}
	else return NO_SELECTED_CARD_ERR;
	
	return 0;
}
//*******************************************************
//*******************************************************
static int iccard_write (      unsigned char *buff,       /* the buffer to fill with data */
				int len       /* the length of the buffer.    */
			)
{
	int i,retval=0;
	unsigned char *txbuf;
	
	txbuf = buff;
	for(i=0;i<len;i++){
		if (i==(len-1)){
			retval= EVOC_send_one_byte(txbuf+i, LAST_BYTE);
			if (retval<0)	return retval;
		}
		else{
			retval= EVOC_send_one_byte(txbuf+i, NOT_LAST_BYTE);		
			if (retval<0)	return retval;			
		}
	}
	
	return len;

}
static int EVOC_iccard_comm(	unsigned char * send_buf,
					  int   send_len,
				unsigned char * rec_buf, 
					  int * rec_len)
{
	int  rlt;
	unsigned char tmp[5];
	unsigned char  *ptr;
	unsigned char  INS;
	unsigned char  first=1;
	int evoc_adpu_Lc,evoc_adpu_Le;

	*rec_len=0;
	
  if (send_len<4)  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;
  	evoc_adpu_Le = tmp[4];
  	evoc_adpu_Lc = -1;
		INS = tmp[1];
		ptr = tmp;						//CLS			
  }
  else if (send_len==5) 
  {
  	evoc_adpu_Le = *(send_buf+4);
  	evoc_adpu_Lc = -1;
		INS = * (send_buf+1);
		ptr = send_buf;						//CLS			
  }	
  else{
 		evoc_adpu_Lc = *(send_buf+4);
 		if (send_len == evoc_adpu_Lc+5) evoc_adpu_Le = -1;
 		else if (send_len == evoc_adpu_Lc+5+1) evoc_adpu_Le = *( send_buf+send_len ); 
 		else return ADPU_ERR;      		

		INS = * (send_buf+1);
		ptr = send_buf;						//CLS			
 	}
        
	if ( ( evoc_adpu_Lc == -1 ) && (evoc_adpu_Le == -1) ) return ADPU_ERR;
	if ( ( evoc_adpu_Lc >= 255 ) || (evoc_adpu_Le >= 255) ) return ADPU_ERR;
	if ( ( evoc_adpu_Lc == 0 ) ) return ADPU_ERR;
	

	rlt=iccard_write(ptr,5);					//发送5字节的命令头
	if (rlt<0)  return rlt;

	ptr = rec_buf;						//接受缓冲首地址
	
	if ( evoc_adpu_Lc != -1 ) 
	{		//写卡, Lc存在且不为0

		while(1)
		{		// receive one byte INS
			rlt = EVOC_rev_one_byte(ptr,TIMEOUT_MAX_CYCLE,NOT_TS_BIT);
			if (rlt<0) 
			{
				*rec_len = 0;
				return rlt;		// time out err or parity err		
			}
				
		  if ( !(*ptr==0x60) )
		  {  //0x60 等待;
				break;
			}
		}				
		
		ptr = send_buf+5;					//数据段首址
		
		if ( ( rec_buf[0]==INS )||( rec_buf[0]==(INS^0x01) ) )
		{
			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
			rlt=iccard_write(ptr,evoc_adpu_Lc);					//发送Lc个字节
			if (rlt<0) return rlt;	
			ptr = rec_buf;					//收的数据
			first = 1;							//重新等待过程字节	
			
			if ( evoc_adpu_Le == 0 ) 
			{
				while(1)
				{
					rlt = EVOC_rev_one_byte(ptr,TIMEOUT_MAX_CYCLE,NOT_TS_BIT);
					if ( rlt==TIMEROUT_ERR) 	return rlt;		// time out exit
					if ( rlt<0 ) 
					{
						*rec_len = 0;
						return rlt;			// parity err
					}
				
				  if ( !((*ptr==0x60)&&(first==1)) )
				  {  //0x60 等待;
					        first=0;
						ptr++;
						(*rec_len)++;
						if ( *rec_len >= 256 ) return 0;						
					}
				}
			}
			else if ( evoc_adpu_Le == -1 )
			{		// Le not exist
				while(1)
				{
					rlt = EVOC_rev_one_byte(ptr,TIMEOUT_MAX_CYCLE,NOT_TS_BIT);
					if (rlt<0) 
					{
						*rec_len = 0;
						return rlt;		// time out err or parity err		
					}
					
					if ( !((*ptr==0x60)&&(first==1)) )
					{  //0x60 等待;
					        first=0;
						ptr++;
						(*rec_len)++;		
						if ( *rec_len >= 2 ) return 0;
					}
				}			
			}
			else
			{					// Le exist
				while(1)
				{
					rlt = EVOC_rev_one_byte(ptr,TIMEOUT_MAX_CYCLE,NOT_TS_BIT);
					if (rlt<0) 
					{
						*rec_len = 0;
						return rlt;		// time out err or parity err		
					}
						
					if ( !((*ptr==0x60)&&(first==1)) )
					{  //0x60 等待;
					  first=0;
						ptr++;
						(*rec_len)++;		
						if ( *rec_len >= evoc_adpu_Le+2 ) 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
		
			rlt=iccard_write(ptr,1);					//发送1字节

			first = 1;							//重新等待过程字节
			while(1)
			{
				rlt = EVOC_rev_one_byte(ptr,TIMEOUT_MAX_CYCLE,NOT_TS_BIT);
				if ( rlt==TIMEROUT_ERR) 	return rlt;		// time out exit
				if ( rlt<0 )
			  {
					*rec_len = 0;
					return rlt;			// parity err
				}
			
			  if ( !((*ptr==0x60)&&(first==1)) )
			  {  //0x60 等待;
				  first=0;
					ptr++;
					(*rec_len)++;
					if ( *rec_len >= 256 ) return 0;
				}				
			}
		}
		else 
		{		// Sw1+ SW2, 收SW2
			ptr++;		//留下上一个收到的字节,是SW1
			(*rec_len)++;			
			rlt = EVOC_rev_one_byte(ptr,TIMEOUT_MAX_CYCLE,NOT_TS_BIT);
			if (rlt<0) 
			{
				*rec_len = 0;
				return rlt;		// time out err or parity err		
			}
			ptr++;
			(*rec_len)++;
			return 0;			
		}	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -