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

📄 ph8550_sc.c

📁 smart card智能卡的读写测试程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/**************************************************************************** *  * Copyright (c) 2007 - 2009 AERO-SPACE INFO Corp. All rights reserved.  * ****************************************************************************/ /**************************************************************************** *  * FILENAME *     Ph8550_sc.c * * VERSION *     1.0 * * DESCRIPTION *     Smart Card driver supported by AeroInfo for PNX8550 SmartCart Uar1. * * FUNCTIONS *	all functions, if they has return value, return 0 if they success, others failed. *    ( see below for detail ) * * HISTORY *	2007/03/01		Ver 1.0 Created by MengFanJie * * REMARK *     None *************************************************************************/#include "Ph8550_sc.h"static unsigned int reset_ss = 0;static SmartCard_Dev smartcard_dev;static unsigned char* p_atr; static sc_parameter para;static unsigned char  PPS_R[6];   static unsigned char  APDU_CMD[MAX_BUF_LEN];static unsigned char  APDU_RESULT[MAX_BUF_LEN];static unsigned int   APDU_CMD_NUM = 0;static unsigned int   APDU_RESULT_MUN = 0;static unsigned char AtrOrWr_flag = 0;void  __inline sc_InitReader(void){	UCR1 = 0x80;     // set RIU bit of UCR1 to one	FCR = 0x100;     //	TOC = 0x01;      // set TOR1 as counter for rstin, TOR2 and TOR3 linked as one timer 	TOR1 = 121;      // set couter is 121 ETU in order to set rstin as high after vcc is high	TOR2 = 0x80;	TOR3 = 0x25;     // set the TOR3-TOR2 as a timer , the delay is 9600 etu	return ; } static int Sc_Rawsccksetting(void){	PDR = 12; 	CCR = 0x05;     // set ac2:ac0 as '100' , so clk_card = core_clk/16.	return 0;}static int Sc_DeactivateCard(void){	UCR2 &= (~0x80);    // reset rstin bit	UCR2 &= (~0x20);    // reset start bit	return 0;} static int Sc_ActivateCard(void){	sc_InitReader();	Sc_Rawsccksetting();      //set the raw clock;		if(MSR & 0x10)  	       // there is a card in card-socked 		smartcard_dev.exist = 1;	else		smartcard_dev.exist = 0;			reset_ss = 0;	UCR1 |= 0x03;    // set the ss bit before ATR 	UCR2 |= 0x20;    // set the start bit as high	TOC = 0x09;      // set the toc1 work in the mode of software triggered with start bit on i/o		return 0;}static int sc_RawRead(char *buf, unsigned int *count){	int tc_num = 0;	if(!smartcard_dev.exist)  // in the state of Deactivate mode		return SC_ERROR_RW_NOCARD; 	for(tc_num = 0; tc_num < *count; tc_num++) 	{  		TOC = 0x81;                        // start to count the timer3 for delay of data  		while(!(USR&0x01) || (USR&0x80))  		{  			if(USR&0x80)  			{ 				SCIF_INT_CLEAR = 0x01;				RER = 0x400;    				return SC_ERROR_RW_OUTTIME;  			}  		}      		buf[tc_num] = URR;  		TOC = 0x01;    // end to count the timer3   		CRE |= 0x01;  		RER = 0x08;    	}	   	if(USR & 0x08)          // parity error happend	{		*count = tc_num;		RER = 0x40; 		#ifdef DEBUG		   printk(KERN_INFO"pe-r\n");		#endif		return SC_ERROR_RW_PE;	}	if(USR & 0x04)  // ovr error happend	{		*count = tc_num;		RER = 0x20;		return SC_ERROR_RW_OVR;	}	*count = tc_num;	return 0;} /*int sc_read(struct file *filp, char *buf, size_t count, loff_t *f_pos){	unsigned int k_count = count;	AtrOrWr_flag = 1;		if(smartcard_dev.state)		return -1;	if(k_count == 0)		return -2;	if( k_count > MAX_BUF_LEN)		k_count = MAX_BUF_LEN-1;	if((smartcard_dev.errno = sc_RawRead(read_local_buf, &k_count))!= 0)		return -3;		if(copy_to_user((void *)buf, (void *)read_local_buf, k_count))		return -4;	*f_pos += k_count;//	AtrOrWr_flag = 0;	return k_count;}*/static int sc_RawWrite(unsigned char *buf, size_t *count){	int tc_num = 0;	if(!smartcard_dev.exist)  // in the state of Deactivate mode		return  SC_ERROR_RW_NOCARD;  	UCR1 |= 0x08;	//set the transmit mode	//wait for the chance to write the char 	for(tc_num = 0; tc_num < *count; tc_num++) 	{   		TOC = 0x81;     // start to count the timer3 for delay of data   		while(!(USR&0x01) || (USR&0x80))   		{			if(USR&0x80)  			{  				SCIF_INT_CLEAR = 0x01;				RER = 0x400;  				UCR1 &= (~0x08);  //set the receive mod				return  SC_ERROR_RW_OUTTIME;  			}		}		//set the transmit mode, is important for warm-reset  		UTR = buf[tc_num];  		TOC = 0x01;     	}	while(!(USR&0x01))		;	if(USR & 0x08)          // parity error happend	{		*count = tc_num;		RER = 0x40;		#ifdef DEBUG			printk(KERN_INFO"AZ\n");		#endif		UCR1 &= (~0x08);  //set the receive mod			return  SC_ERROR_RW_PE;	}	if(USR & 0x04)  // ovr error happend	{		*count = tc_num;		RER = 0x20;		#ifdef DEBUG			printk(KERN_INFO"AAZ\n");		#endif		UCR1 &= (~0x08);  //set the receive mod			return  SC_ERROR_RW_OVR;	}	*count = tc_num;   	UCR1 &= (~0x08);  //set the receive mod	return 0;} /*int sc_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos){	unsigned int k_count = 0;	AtrOrWr_flag = 1;		k_count = count;	if(smartcard_dev.state)		return -1;	if(count == 0)		return -2;	if( count > MAX_BUF_LEN)		count = MAX_BUF_LEN;			if(copy_from_user(write_local_buf, buf, k_count))		return -3;		     	if((smartcard_dev.errno = sc_RawWrite(write_local_buf, &k_count))!= 0)		return -4;	*f_pos += k_count;		return k_count;} */static int sc_InsertOrRemove(void){		if((MSR & 0x18) == 0x18)	{		printk(KERN_INFO"card insert\n");		SCIF_INT_ENABLE = 0x0cff;		smartcard_dev.atr_len = 0;		p_atr = smartcard_dev.atr_buffer;		Sc_ActivateCard();				}	else 	{		AtrOrWr_flag = 0;		smartcard_dev.exist = 0;		printk(KERN_INFO"card outside\n");		smartcard_dev.exist = 0;   // the card is removed 		Sc_DeactivateCard();	}	SCIF_INT_CLEAR = 0x400;        //  clear OCH interrupt		RER = 0x2000; 	return 0;}static int sc_RstinToHigh(void){  	UCR2 |= 0x80; 	               // set the rstin as high;	#ifdef DEBUG	      			printk(KERN_INFO"TOR1\n");  	#endif                           	SCIF_INT_CLEAR = 0x20;         // clear TO1 interrupt		RER = 0x100;                   // reset TO1 bit	return 0;}static int sc_TOR3Interrupt(void){  	SCIF_INT_CLEAR = 0x80;         // clear TO3 interrupt		#ifdef DEBUG		printk(KERN_INFO"TOR3\n");	#endif	return 0;}static int sc_TOR2Interrupt(void){  	SCIF_INT_CLEAR = 0x40;         // clear TOR2 interrupt		RER = 0x200;  	#ifdef DEBUG   		printk(KERN_INFO"TOR2\n");	#endif	return 0;}static int sc_OVRInterrupt(void){		SCIF_INT_CLEAR = 0x04;	#ifdef DEBUG		printk(KERN_INFO"OVR\n");	#endif	return 0;}static int sc_ReceiveATR(void){    *p_atr = URR;      p_atr++;     smartcard_dev.atr_len++;     if(!reset_ss)     {	UCR1 &= 0xfffffffd;  //reset ss bit 	reset_ss = 1;     }     SCIF_INT_CLEAR = 0x01;     CRE |= 0x01;              RER = 0x08;     return 0;}static int sc_DMADone(void){               SCIF_INT_CLEAR = 0x800;     RER = 0x8000;        return 0;}static int sc_EA_Interrupt(void){                SCIF_INT_CLEAR = 0x10;      RER = 0x80;     #ifdef DEBUG      	printk(KERN_INFO"EA\n");     #endif     return 0;}static int sc_FER_Interrupt(void){                SCIF_INT_CLEAR = 0x02;      RER = 0x10;      #ifdef DEBUG      	printk(KERN_INFO"FER\n");     #endif     return 0;}static int sc_ParityError(void){                  SCIF_INT_CLEAR = 0x08;     #ifdef DEBUG     	printk(KERN_INFO"PE\n");     #endif     return 0;}static int sc_DMAABORT_Interrupt(void){                SCIF_INT_CLEAR = 0x100;     RER = 0x800;       #ifdef DEBUG     	printk(KERN_INFO"DMAABORT\n");     #endif     return 0;}static int sc_DMAERROR_Interrupt(void){            SCIF_INT_CLEAR = 0x200;     RER = 0x1000;       #ifdef DEBUG        	 printk(KERN_INFO"DMAERROR\n");     #endif     return 0;}static int warm_reset(void){	UCR2 &= (~0x80);          // reset the reset	sc_InitReader();	Sc_Rawsccksetting();      //set the raw clock;	UCR1 |= 0x03;             // set the ss bit before ATR 	UCR1 &= (~0x08);          //set the receive mod	AtrOrWr_flag = 0;	smartcard_dev.atr_len = 0;	p_atr = smartcard_dev.atr_buffer;	reset_ss = 0;	SCIF_INT_ENABLE = 0x0cff;	TOC = 0x09;      // set the toc1 work in the mode of software triggered with start bit on i/o		return 0;}irqreturn_t sc_Interrupt(int irq, void * dev_id, struct pt_regs *regs){	unsigned int status = SCIF_INT_STATUS;	if(status & 0x01)	{		if(!AtrOrWr_flag)			sc_ReceiveATR();		else			SCIF_INT_CLEAR = 0x01;			return 0;	}	else if(status & 0x02)	{		sc_FER_Interrupt();		return 0;	}	else if(status & 0x04) 	{         		sc_OVRInterrupt(); 		return 0;	}	else if(status & 0x08)	{		sc_ParityError();		return 0;	}	else if(status & 0x10)	{		sc_EA_Interrupt();		return 0;	}		else if(status & 0x20)	{		sc_RstinToHigh();		return 0;	} 	else if(status & 0x40)	{		sc_TOR2Interrupt();		return 0;	} 	else if(status & 0x80)	{		sc_TOR3Interrupt();		return 0;	} 	else if(status & 0x100)	{		sc_DMAABORT_Interrupt();		return 0;	}	else if(status & 0x200)	{	sc_DMAERROR_Interrupt();		return 0;	}		else if(status & 0x400)	{                   // BOF or OCH happens in MSR 		sc_InsertOrRemove();		return 0;	}	else if(status & 0x800)	{		sc_DMADone();		return 0;	}	return 0;}static int sc_open(struct inode *inode, struct file *filp){	unsigned char irq_result = 255;	if(smartcard_dev.openflag)		/* one card slot, one open */		return -1;	else		smartcard_dev.openflag = 1;	try_module_get(THIS_MODULE);			irq_result = request_irq(SMARTCARD_IRQ_NO, &sc_Interrupt,SA_INTERRUPT, "smcard", NULL);	//disable_irq(SMARTCARD_IRQ_NO);          //enable_irq(SMARTCARD_IRQ_NO);       	SCIF_INT_ENABLE = 0x0cff;      	#ifdef DEBUG      		printk(KERN_INFO"irq_result = %d\n",irq_result);      	#endif       	smartcard_dev.atr_len = 0;	p_atr = smartcard_dev.atr_buffer;	if(MSR & 0x10)                              // there is a card in card-socked 		Sc_ActivateCard();	printk(KERN_INFO"card open!\n");	return 0;}static int sc_release(struct inode *inode, struct file *flip){	AtrOrWr_flag = 0;	if(smartcard_dev.openflag)           /* no card in slot, close */		smartcard_dev.openflag  = 0;	else		return -1;	SCIF_INT_ENABLE = 0x0; 	free_irq(SMARTCARD_IRQ_NO, NULL);	module_put(THIS_MODULE);	Sc_DeactivateCard();	printk(KERN_INFO"card close!\n");	return 0;}static int sc_SetDivClock(unsigned char ac){	unsigned char ccr_val = 0;		ccr_val = CCR;	CCR = (ccr_val & 0xf8)+ ac;	smartcard_dev.clock = 54*1024/supported_div_Hz[ac].multiple;	return 0;}static int sc_SetBaudRate(int fi, int di){	int i;	int find_baudrate = 0;	/* check error is done already */

⌨️ 快捷键说明

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