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

📄 iccard.c

📁 嵌入式系统上用的SMARTCARD的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
						*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
				//printk("%s: parity_bit = 1\n");
				return 0;
			}
		}
		else
		{
			parity_bit = 0;
			if (rev_TS==TS_BIT){
				//printk("PARITY1_ERR  rev_TS==TS_BIT\n");
				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:
		//delay_one_etu();		//10.5 etu 
		
		CARD_TX_CLR;
    
		delay_one_etu();		//11.5 etu 
		if (card_selected==SAMCARD) delay_half_etu_sam();		//0.5etu
		else delay_half_etu_usr();		//12 etu
		
		CARD_TX_SET;	
		
		if (card_selected==SAMCARD) delay_half_etu_sam();		//0.5etu
		else delay_half_etu_usr();		//12.5 etu		
		re_rev_times++;
		//printk("PARITY1_ERR %d\n",*revdata);		
	}
	//temp = revdata;
	//printk("%s: temp = %d",__file__,temp);
	return 	PARITY1_ERR;
}
//*******************************************************
//*******************************************************
static int iccard_reset(	unsigned char * rec_buf,
			int  * rec_len)

{

	int rlt,i,j,m;
	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(2500);
				
		EVOC_sam_set_card_rst();
		
		delay_cycle(5000);
		
		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(2500);
		
		EVOC_usr_set_card_rst();
		
		delay_cycle(5000); 
		
		
		EVOC_usr_clr_card_rst();
	}
	else return NO_SELECTED_CARD_ERR;	
	//delay_cycle(200);	
	ptr = rec_buf;
	*card_logic_mode = POSITIVE_LOGIC;
	/*
	memset(rec_buf,0x00,20);
  for(j=0;j<20;j++)
 	{
 			rlt = EVOC_rev_one_byte(ptr++,REV_TS_TIMEOUT_CYCLE,NOT_TS_BIT);		//receive TS
			if (rlt<0) {
				*rec_len = 0;
				break;		// time out err or parity err		
			}
			//if(j==2) delay_cycle(15000);
 	}
  printk("j=%d\n",j);
	printk("0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n
	        0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n
	        0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n
	        0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n",
  rec_buf[0],rec_buf[1],rec_buf[2],rec_buf[3],rec_buf[4],
  rec_buf[5],rec_buf[6],rec_buf[7],rec_buf[8],rec_buf[9],
  rec_buf[10],rec_buf[11],rec_buf[12],rec_buf[13],rec_buf[14],
  rec_buf[15],rec_buf[16],rec_buf[17],rec_buf[18],rec_buf[19]
  );
  return 0;
  */
	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 = %d\n",__file__,ptr[0]);
		*rec_len = 0;		
		return CARD_ERR;
	}
	
	//printk("%s: *ptr = %d\n",__file__,ptr[0]);
	
	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;
	m=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)
			m++;
			if (rlt<0) 
			{
				*rec_len = 0;
				return rlt;		// time out err or parity err		
			}
			i++;
			/*if((i==2)&&(card_selected==SAMCARD))
			{
				*(++ptr) = 0;
				break;
			}*/
			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++;
	}
	/*
	printk("0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n
	       m = %d\n",			    
		  rec_buf[0],rec_buf[1],rec_buf[2],rec_buf[3],
		  rec_buf[4],rec_buf[5],m);	
		  */			
	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;
	//printk("0x%2x 0x%2x 0x%2x 0x%2x 0x%2x \n",rec_buf[0],rec_buf[1],rec_buf[2],rec_buf[3],rec_buf[4]);
	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;
			/*
			printk("i=%d\n",i);
			printk("0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n
			        0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n
			        0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n
			        0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n",
		  rec_buf[0],rec_buf[1],rec_buf[2],rec_buf[3],rec_buf[4],
		  rec_buf[5],rec_buf[6],rec_buf[7],rec_buf[8],rec_buf[9],
		  rec_buf[10],rec_buf[11],rec_buf[12],rec_buf[13],rec_buf[14],
		  rec_buf[15],rec_buf[16],rec_buf[17],rec_buf[18],rec_buf[19]
		  );*/
			return rlt;		// time out err or parity err		
		}
		i++;
	}
  //printk("%s:line706\n",__file__);
	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;
	int count;
	int ii = 0;
	unsigned char tmp[5];
	unsigned char  *ptr;
	unsigned char  INS;
	unsigned char  first=1;
	int s3c_adpu_Lc,s3c_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;
        	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 
       		{      
       				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;
	

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

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

		while(1){		// receive one byte INS
			rlt = EVOC_rev_one_byte(ptr,usrcard_max_cycle,NOT_TS_BIT);
			if (rlt<0) {
				*rec_len = 0;
				return rlt;		// time out err or parity err		
			}
				
		if ( !(*ptr==0x60) ){  //0x60 等待;
				break;
			}
		}				
		count = 0;
		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,s3c_adpu_Lc);					//发送Lc个字节
			if (rlt<0) return rlt;
			//delay_one_etu();
			//delay_one_etu();
			ptr = rec_buf;					//收的数据
			first = 1;							//重新等待过程字节	
			
			if ( s3c_adpu_Le == 0 ) {
				while(1){
					rlt = EVOC_rev_one_byte(ptr,usrcard_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 ( s3c_adpu_Le == -1 ){		// Le not exist
				while(1){
					rlt = EVOC_rev_one_byte(ptr,usrcard_max_cycle,NOT_TS_BIT);
					ii++;
					if (rlt<0) {						
						printk("%s\n rece err\n ii = %d\n *ptr = %2x\n rec_len = %d\n",
						        __file__,ii,*ptr,*rec_len);
						*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,usrcard_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 >= s3c_adpu_Le+2 ) return 0;
					}
				}	
			}

		}
		else if( ( rec_buf[0]==(INS^0xff) )||( rec_buf[0]==(INS^0xfe) ) ){	
		repeat:	
			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,usrcard_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 等待;
					 if((( *ptr==(INS^0xff) )||( *ptr==(INS^0xfe)))&&(count<s3c_adpu_Lc-1))
			 			{					 		
					 		count++;
					 		ptr = send_buf+5+count;				 		
					 		if(count>=s3c_adpu_Lc-1)ptr = rec_buf;
					 		goto repeat;
			 			}	
					first = 0;
					ptr++;

⌨️ 快捷键说明

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