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

📄 iccard0911.c

📁 嵌入式系统上用的SMARTCARD的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
//*******************************************************
static int EVOC_rev_one_byte(unsigned char * rev_data, unsigned int timeout, int rev_TS){

	unsigned char * revdata;
	unsigned int  i;
	unsigned long count;
	int re_rev_times;
	unsigned char parity_bit;
	int card_logic_mode;
	
	if (card_selected==SAMCARD) 
	{
		card_logic_mode = logic_mode_sam;		
	}
	else if(card_selected==USRCARD)
	{
		card_logic_mode = logic_mode_usr;
	}
	else return NO_SELECTED_CARD_ERR;
	
	re_rev_times = 0;
	revdata = rev_data;
	
	while ( re_rev_times < RE_REVEIVE_TIMES )
	{
		if (card_selected==SAMCARD) 
		{
			//EVOC_select_sam();
		}
		else if(card_selected==USRCARD)	
		{
			//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;
	unsigned char	DatBuf[50];
	memset(DatBuf,0, sizeof(DatBuf));
	*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;	
		
	*card_logic_mode = POSITIVE_LOGIC;
	for (i=0; i<13; i++)
	{
			//RecvCardByte(&DatBuf[i],MAX_TIME_OUT);
			//RecvCardByte(&DatBuf[i],MAX_TIME_OUT);
			rlt = EVOC_rev_one_byte(&DatBuf[i],REV_TS_TIMEOUT_CYCLE,TS_BIT);		//receive TS
			if (rlt)
			{
				//ErrFlag =iRet;
				printk("\nRecvCardByte() TIME OUT\n");
				return	1;
			}
		
	}
		
	//if ((DatBuf[0] != 0x3b)&&(DatBuf[0] != 0x3f))
	//{
	//		printk("\n RESET ERROR");
	//		iRet = 1;
	//}
	//else
	//		iRet =0;
	for (i=0;i<13;i++) 
		printk("nread=%d  data=%x \n",i,DatBuf[i]);

}
//*******************************************************
//*******************************************************
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;			
		}	
	}
	else{		//读卡,Lc 不存在(-1)
		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;
			}
		}		
	
		if ( ( rec_buf[0]==INS )||( rec_buf[0]==(INS^0x01) ) )
		{
				
			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

⌨️ 快捷键说明

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