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

📄 iccard.b.c

📁 嵌入式系统上用的SMARTCARD的驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
	}
	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
					}
					ptr++;
					(*rec_len)++;
					if ( *rec_len >= 256 ) return 0;
				}
			}
			else
			{		// Le !=0 && !=-1 (因为Le和Lc不能同时为-1)
				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		
					}
					ptr++;
					(*rec_len)++;		
					if ( *rec_len >= evoc_adpu_Le+2 ) return 0;
				}	
			}
		}
		else if( ( rec_buf[0]==(INS^0xff) )||( rec_buf[0]==(INS^0xfe) ) )
		{
			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
				}
				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;			
		}			
	}
}
//******************************************************
//******************************************************
static void enable_Time1(u_int32_t time_per)
{
		u_int32_t tmod;
		outl(time_per, S3C44B0X_TCNTB1);
		s3c44b0x_unmask_irq(S3C44B0X_INTERRUPT_TIMER1);		
		tmod = inl(S3C44B0X_TCON);
		tmod |= S3C44B0X_TCON_T1_START;
		outl(tmod, S3C44B0X_TCON);
}
//******************************************************
//******************************************************
static void disable_Time1(void)
{
		u_int32_t tmod;
		s3c44b0x_mask_irq(S3C44B0X_INTERRUPT_TIMER1);
		tmod = inl(S3C44B0X_TCON);
		//tmod=0;
		tmod &= ~(S3C44B0X_TCON_T1_START);
		outl(tmod, S3C44B0X_TCON);
}
//*******************************************************
//*******************************************************
static void setup_timer (void)
{
	__u32 rw_tmp;
  
  u_int32_t tmod;
  outl(0x778,S3C44B0X_TCNTB1);
	tmod = inl(S3C44B0X_TCON);
	//tmod=0;
	tmod |= S3C44B0X_TCON_T1_MAN_UPDATE;
	outl(tmod, S3C44B0X_TCON);

	/* initialize the timer period and prescaler */
	rw_tmp  = inl(S3C44B0X_TCFG0);
	rw_tmp &= ~(0xff<<0);
	rw_tmp |= (1)<<0;
	outl(rw_tmp, S3C44B0X_TCFG0);		// prescaler = 1
	
	rw_tmp  = inl(S3C44B0X_TCFG1);
	rw_tmp &= ~(0xf<<0);
	rw_tmp |= 0<<0;
	outl(rw_tmp, S3C44B0X_TCFG1);		// mux = 1/2
	//disable_Time1();
	
	s3c44b0x_unmask_irq(S3C44B0X_INTERRUPT_TIMER1);		
	//tmod = inl(S3C44B0X_TCON);
	//tmod=0;
	//tmod |= S3C44B0X_TCON_T1_AUTO;
	//tmod |= S3C44B0X_TCON_T1_START;
	//outl(tmod, S3C44B0X_TCON);
		
	outl(0x05, S3C44B0X_INTCON);
	
}

/*----------------------------------------------------------------------------*/
/* file_operations functions -------------------------------------------------*/

static ssize_t EVOC_iccard_write (struct file *file,
                        char *buff,       /* the buffer to fill with data */
			size_t len,       /* the length of the buffer.    */
			loff_t *offset) 
{ /* Our offset in the file       */

			int retval=0;
			
		  char txbuf[EVOC_ICCARD_BUF_SIZE];
			
			if ((len>=sizeof(txbuf))||(len<=0))	return -EINVAL;
		  	copy_from_user( txbuf, buff, len);
			
		
			if (card_selected==SAMCARD) {
				EVOC_select_sam();
				delay_cycle(1000);
				if (samcard_err<0) return -1;
			}
			else if(card_selected==USRCARD){
				EVOC_select_usr();
				delay_cycle(1000);
				if (usrcard_err<0) return -1;
			}
			else return NO_SELECTED_CARD_ERR;	
		
			retval = EVOC_iccard_comm(txbuf,len,iccardfifo.buffer,&iccardfifo.len);
			
			if (card_selected==SAMCARD) {
				samcard_err = retval;
			}
			else if(card_selected==USRCARD){
				usrcard_err = retval;
			}
			else return NO_SELECTED_CARD_ERR;	
		#ifdef DEBUG_ICCARD	
				EVOC_show_card_err_msg(retval);
		#endif	
			return retval;

}

/*
 * Called whenever a process attempts to read the device it has already open.
 */

static ssize_t EVOC_iccard_read (struct file *file,
                        char *buff,       /* the buffer to fill with data */
			size_t len,       /* the length of the buffer.    */
			loff_t *offset) 
{ /* Our offset in the file       */	
	int retval = 0;
	
	//sti();	
	if (iccardfifo.len==0) retval=0;
	else 
	{
		retval = iccardfifo.len;
		if ( copy_to_user (buff, iccardfifo.buffer, iccardfifo.len) )
			retval = -EFAULT;
	}	
	iccardfifo.len = 0;
		
  return retval;
}

/*
 * Called whenever a process attempts to do an ioctl to the device it has
 * already open.
 */
static int EVOC_iccard_ioctl(struct inode *inode, struct file *file,
		    unsigned int cmd,     /* the command to the ioctl */
		    unsigned long arg) {  /* the parameter to it      */
	
   int retval=0;
   char flag_test=0;
   switch (cmd) 
   {
		  case EVOC_CARD_SELECT:
				if      ( arg == SAMCARD ) card_selected = SAMCARD;
				else if ( arg == USRCARD ) card_selected = USRCARD;
				else		 	   card_selected = NONECARD;
			break;
		  case EVOC_CARD_RESET:
				if ( card_selected == USRCARD )
			     if (usrcard_err == NO_CARD_ERR) return -1;			        
				retval = EVOC_iccard_reset( iccardfifo.buffer, &iccardfifo.len, card_selected );
				#ifdef DEBUG_ICCARD	
						EVOC_show_card_err_msg(retval);
				#endif
				return retval;
			
			break;	
		  case EVOC_CARD_STATUS:
				if( card_selected == SAMCARD ) 
				{
					if ((retval = put_user(samcard_err, (int *)arg)) < 0)
						  return retval;
				}
				else if ( card_selected == USRCARD ) 
				{
					if ((retval = put_user(usrcard_err, (int *)arg)) < 0)
						return retval;
			  }
				else		 	   return -EINVAL;
			break;    
		  case EVOC_CARD_POWER_OFF:
				if ( card_selected == SAMCARD ) 	EVOC_sam_card_release();
				if ( card_selected == USRCARD ) 	EVOC_usr_card_release();
			break;
			case EVOC_USR_CARD_ERR:
			  printk("usrcard_err = %d\n",usrcard_err);
			  if ((retval = put_user(usrcard_err, (int *)arg)) < 0)
			 		return retval;
			break; 
			case EVOC_SAM_CARD_ERR:
				printk("samcard_err = %d\n",samcard_err);
				if ((retval = put_user(samcard_err, (int *)arg)) < 0)
					return retval;
			break; 
			case EVOC_START_TEST_ETU:
				printk("start half etu time1\n");
				enable_Time1(0x1fff);
				EVOC_select_usr();
				while(1)
				{
					 if(flag_test==0)
					 {
					 		flag_test=1;
					 		CARD_TX_CLR;
					 }
					 else
					 {
					 		flag_test=0;
					 		CARD_TX_SET;
					 }
					 delay_half_etu();					 
				}
			break;
			case EVOC_STOP_TEST_ETU:
				
				printk("start one etu time1\n");
				EVOC_select_sam();
				while(1)
				{
					 if(flag_test==0)
					 {
					 		flag_test=1;
					 		CARD_TX_CLR;
					 }
					 else
					 {
					 		flag_test=0;
					 		CARD_TX_SET;
					 }
					 delay_one_etu();					 
				}
				//disable_Time1();
			break; 
			case EVOC_IC_PIN_TEST:
				printk("IC_PIN_TEST\n");
				switch (arg)
				{
						case SAM_SET_REST:
							EVOC_sam_set_card_rst();
						break;
						case SAM_CLR_REST:
							EVOC_sam_clr_card_rst();
						break;
						case USR_SET_REST:
							EVOC_usr_set_card_rst();
						break;
						case USR_CLR_REST:
							EVOC_usr_clr_card_rst();
						break;
						case SAM_POW_ON:
							EVOC_sam_card_pwr_on();
						break;
						case SAM_POW_OFF:
							EVOC_sam_card_pwr_off();
						break;
						case USR_POW_ON:
							EVOC_usr_card_pwr_on();
						break;
						case USR_POW_OFF:
							EVOC_usr_card_pwr_off();
						break;
						case LED_POW_ON:
							EVOC_LED_ON();
						break;
						case LED_POW_OFF:
							EVOC_LED_OFF();
						break;
						default:
			      break;
				}				
			break;    
		  default:
				return -EINVAL;
			break;
   }
    return 0;
}
	    
/*
 * Called whenever a process attempts to open the device file.
 */
static int EVOC_iccard_open(struct inode *inode, struct file *file) {
  	int err;
  	//int i;
  	//unsigned char b;
  	unsigned long flag;
  	
  	if(iccard_device_open) return -EBUSY;	  
  	MOD_INC_USE_COUNT;

  	/* And my own counter too */
  	iccard_device_open++;
	
		//EVOC_iccard_reset( iccardfifo.buffer, &iccardfifo.len, SAMCARD);
		
	//#ifdef DEBUG_ICCARD	
		//printk("\nRead %d bytes from sam iccard reset: \n",iccardfifo.len); 
		//for (i=0;i<iccardfifo.len;i++) 
			//printk("nread=%d  data=%x \n",i,iccardfifo.buffer[i]);
	//#endif
	
	//#ifdef DEBUG_ICCARD
		//printk("\nRead %d bytes from usr iccard reset: \n",iccardfifo.len); 
		//for (i=0;i<iccardfifo.len;i++) 
			//printk("nread=%d  data=%x \n",i,iccardfifo.buffer[i]);
	//#endif
	card_selected=NONECARD;	

	//init buffer
	iccardfifo.len = 0;		
  EVOC_iccard_set_port();
	//	if (err<0) printk("open err\n");
	#ifdef DEBUG_ICCARD	
		printk("iccard open ok\n");
	#endif
	
		err=request_irq(S3C44B0X_INTERRUPT_TIMER1,etu_time_handle,0,DEVICE_NAME,NULL);
	if(err<0)
    printk("%s: Error registering the device\n", __file__);
  else
    printk("%s: S3C44B0X_INTERRUPT_TIMER1 IRQ : %d\n",
    __file__,S3C44B0X_INTERRUPT_TIMER1);
  local_irq_save(flag);
  //printk("%s: local_irq_save exis\n",__file__);
  setup_timer();
  //printk("%s: setup_time1\n",__file__);
  local_irq_restore(flag); 
  //cli();
  printk("time_flag11 = %d\n",time_flag); 
  //enable_Time1(0xfff);
  //while(time_flag!=1);
  printk("time_flag = %d\n",time_flag);
  disable_Time1(); 
  return 0;  /* open succeed */
}
 
/*
 * Called whenever a process attempts to close the device file.
 */

static int EVOC_iccard_release(struct inode *inode, struct file *file) 
{

	card_selected = NONECARD;
	EVOC_sam_card_release();
	EVOC_usr_card_release();
	free_irq(S3C44B0X_INTERRUPT_TIMER1,NULL);
	MOD_DEC_USE_COUNT;
  /* And my own counter too */
  iccard_device_open--;
  	
  return 0;
}

static struct file_operations iccard_fops = {
  	owner:          THIS_MODULE,
  	read:           EVOC_iccard_read,
  	ioctl:          EVOC_iccard_ioctl,
  	open:           EVOC_iccard_open,
  	release:        EVOC_iccard_release,
  	write:					EVOC_iccard_write,  
};

/*
 * miscdevice structure for misc driver registration.
 */

/*
 * Initialize the driver.
 */
static int __init EVOC_iccard_init(void) 
{
  	int err;	
  	/* Register the misc device driver */
  	EVOC_iccard_set_port();
  	EVOC_sam_card_release();
	  EVOC_usr_card_release();
  	err = register_chrdev(IC_MAJOR,DEVICE_NAME,&iccard_fops);
  	if(err<0)
    		printk("%s: Error registering the device\n", __file__);
  	else
    		printk("%s: Device register with name: %s and number: %d %d\n",
			   __file__, DEVICE_NAME, IC_MAJOR, IC_MINOR);
	#ifdef CONFIG_DEVFS_FS
	  devfs_ICraw=devfs_register(NULL,"iccard",
	               DEVFS_FL_DEFAULT,IC_MAJOR,IC_MINOR,
	               S_IFCHR|S_IRUSR|S_IWUSR,&iccard_fops,NULL);
  #endif
		printk("%s initialized\n",DEVICE_NAME);		
  	return 0;     /* A non zero value means that init_module failed */
}

/*
 * Cleanup - undid whatever EVOCl03_init did.
 */
void EVOC_iccard_cleanup(void) {
        /* IRQ have to be freed after the hardware is instructed not to interrupt
         * the processor any more.
         */
#ifdef CONFIG_DEVFS_FS
	devfs_unregister(devfs_ICraw);
#endif
  unregister_chrdev(IC_MAJOR,DEVICE_NAME);
  
}  

module_init(EVOC_iccard_init);
module_exit(EVOC_iccard_cleanup);

⌨️ 快捷键说明

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