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

📄 smartcardinterfacedrv.c

📁 凌阳公司机sunplus1002在这个芯片下
💻 C
字号:
/******************************************************************************  Module Name: smartCardDrv Description: This is smartCard Interface device driver,provide the asynchronization and synchronization send  		     and receive the data from the card	 Copyright @ 2006 Sunmedia, Inc. All rights reserved. History: Created by zhangjie on 6/15/2006 *****************************************************************************/#include <cyg/kernel/kapi.h>#include <cyg/hal/plf_intr.h>#include <cyg/io/io.h>#include <cyg/hal/types.h>#include <cyg/infra/diag.h>#include "types.h"#include "string.h"#include "smartCardInterfaceDrv.h"#include "util/sp_timer.h"#define SMC_ENABLE      0x0010#define FSYS_MULT_101_25     3.75           // 0 (base frequency)#define FSYS_MULT_108        4.0            // 1#define FSYS_MULT_114_75     4.25           // 2#define FSYS_MULT_121_5      4.5            // 3#define FSYS_MULT_128_25     4.75           // 4#define FSYS_MULT_135        5.0            // 5//sys clock must set to the actual value!!! it's very important!!!#define	SYSCLK		((int)(FSYS_MULT_108 * 27000000))#define	BAUDC(f)	((UINT32)(SYSCLK / (16.0 * (f)) + 0.5) - 1)//// uart clock divisor// 		81MHz//	9600	020e//	115200	002b	3f//#define	UART_BAUD_9600	BAUDC(9600)(9600)#define	UART_BAUD_57600	BAUDC(57600)#define	UART_BAUD_115200	BAUDC(115200)#define	UART_BAUD_230400	BAUDC(230400)#define	UART_BAUD_460800	BAUDC(460800)#define	UART_BAUD_921600	BAUDC(921600)#define	UART_BAUD_88200 	BAUDC(88200)#define	UART1_SET_BAUDRATE(x)	do { 				\				  regs0->uart1_div_h = (x>>8);		\				  regs0->uart1_div_l = (x);			\				} while (0)#define GET_TIME()  ((regs0->stc_31_16 << 16 | regs0->stc_15_0) / 90)		 #define SMC_VECTOR CYGNUM_HAL_INTERRUPT_UART1/********************************************************************************							internal variable********************************************************************************/static cyg_interrupt int_smc;static cyg_handle_t int_smc_hd;static UINT8 art[32]; // ack for reststatic UINT8 artLen; // length of the ackstatic UINT8 rxBuf[256]; //receive bufferstatic UINT8 rxPtr = 0;  //receive pointerstatic UINT8 overrun = 0;static UINT8 rxNum = 0; //want to receive the number of the bytesstatic UINT8 rxCompleted = 0; //receive completedstatic UINT8 txBuf[256]; //tranmit bufferstatic UINT8 txPtr = 0;  //tranmit pointerstatic UINT8 txNum = 0;//want to transmit the number of the bytesstatic UINT8 txCompleted = 0; //transmit completedstatic UINT8 deviceStatus = 0; //0 idel, 1 busystatic UINT32 startTime = 0; //receive start timestatic UINT32 endTime = 0; //receive complete time it judge the receive timeoutstatic UINT16 uart1_irsm_isc;static UINT16 uart1_isc;static UINT16 uart1_lsr;static UINT8 isTimeout = 0; /********************************************************************************							internal function********************************************************************************/static void initalETU(void);void readART(void);static void handleTimeout(void);/****************************************************************************** Prototype: 	void initSMCInterface Parameters:	no Returns: 	no Description:	 	1. set the HE1000, config the smc interface Restrictions:				 *****************************************************************************/void initSMCInterface(void){    short	template_isc;	//for sm isc reg    short	template_ctrl;	//for sm ctrl reg    short  templat;     initalETU();    //disable UA1 on cfg3    regs0->sft_cfg3 &=  ~(7 << 11);    //disable PCI and enable SMC on cfg2    regs0->sft_cfg2 &=  ~(3 << 14);    regs0->sft_cfg2 |= SMC_ENABLE;    //enable SCIE and SCWE    template_isc = ISC_SCIE | ISC_SCWE;    IRSM_ISC(template_isc);    //enable uart1 txm, rxm, and lsm   // regs0->uart1_isc |= (ISC_LSM | ISC_RXM | ISC_TXM);       //clk to 8004 :    //CLK signal: SMC_CLK = SYSCLK/(2C+2)    //write uart1_sm_clk 0x0010 : 108 / (2 * 14 +2) = 3.58MHz  //  regs0->uart1_sm_clk = 0x0E;    regs0->uart1_sm_clk = 0x05 ;//test    regs0->uart1_sm_egt = 0xa02;    template_ctrl = (SM_IO+SM_TS+SM_REPC+SM_RETRY+SM_EGT+REPC_THR+RETRY_THR);    SM_CTRL(template_ctrl);    templat = (SM_PROTECTION+SM_PRES_P+SM_VOT_OFF+SM_CTRL_PASS); //default power off    SM_IF(templat);    //control reset high    regs0->uart1_sm_if |= (1<<2);    createTimer();    registerTimerCallback(handleTimeout);}/****************************************************************************** Prototype: 	static void initalETU Parameters:	no Returns: 	no Description:	 	1. set the smarcard interface device initial etu = 1/9600 s 	2. set the data format: even parity, 8bit word length Restrictions:				 *****************************************************************************/static void initalETU(void){//	UART1_SET_BAUDRATE(BAUDC(9600));	regs0->uart1_div_h = 1;	regs0->uart1_div_l = 0x16;	regs0->uart1_lcr = 0x1F; }/****************************************************************************** Prototype: 	static void rest(void) Parameters:	no Returns: 	no Description:	 	1. set the smarcard interface device initial etu = 1/9600 s Restrictions:				 *****************************************************************************/ void restSmartCard(void){	int i;        regs0->uart1_sm_if |= ~SM_VOT_ON;        regs0->uart1_sm_if &= SM_RST_ON;        regs0->uart1_sm_if &= SM_CLK_OFF;        txPtr = txNum = rxNum = rxPtr = deviceStatus= 0;    	//Activate CTRL PASS    	regs0->uart1_sm_if |= SM_CTRL_PASS;    	//Note: this step must after CTRL_PASS, so that no Cin int issue again	    	regs0->uart1_irsm_isc = SM_NO_INT<<8;    	for(i=0; i<3; i++) {}			//Wait a little time   	 regs0->uart1_sm_if &= SM_VOT_ON;		//Power on    	for(i=0; i<3; i++) {}     	regs0->uart1_sm_if |=SM_CLK_ON;	//Clocl on     	for(i=0; i<ACTIVATION_GAP; i++) {}	//400 SM_CLK (tb time)     	regs0->uart1_sm_ctrl |= SM_RX_RST|SM_TX_RST; //clear the data     	regs0->uart1_sm_if |= SM_RST_OFF; //Reset off     	//enable the plug in and withdraw interrupt    	regs0->uart1_irsm_isc =ISC_SCIE | ISC_SCWE;    	i = regs0->uart1_irsm_isc ; //clear the SCII status}/****************************************************************************** Prototype: 	static int readByte(UINT8* data) Parameters:	UINT8* data output data Returns: 	0 sucessufl, -1 timeout fail Description:	 	1. read data from the smartcard Restrictions:				 *****************************************************************************/static int readByte(UINT8* data){	UINT32 uiStartTime, uiEndTime;	uiStartTime = GET_TIME(); // 1ms(uint)	uiEndTime = uiStartTime; 	while ((!(regs0->uart1_lsr & UART_RX_RDY)) && ((uiEndTime - uiStartTime) < 1000))       {		uiEndTime = GET_TIME();	}	if (regs0->uart1_lsr & UART_RX_RDY)	{		*data = regs0->uart1_data;		return 0;	} else {		return -1;//timeout	}}/****************************************************************************** Prototype: 	static void readART(void) Parameters:	no Returns: 	no Description:	 	1. read the smartcard answer to rest Restrictions:				 *****************************************************************************/void readART(void){	int i = 0;	for (;;) {		if ((readByte(art+i) != 0) || i >31)		{			artLen = i;			break;		}		i++;	}}/****************************************************************************** Prototype: 	int getART(UINT8 *buf )  Parameters:	UINT8 *buf copy the answer rest to the buf Returns: 	the length of the answer rest Description:	 	1. get the smartcard answer to rest for application Restrictions:				 *****************************************************************************/int getART(UINT8 *buf ) {	memcpy(buf,art, artLen);	return artLen;}/****************************************************************************** Prototype: cyg_uint32 isr_smc(cyg_vector_t vector,  cyg_addrword_t data) Parameters:	cyg_vector_t vector, cyg_addrword_t data Returns: 	 Description:	 	1. the smartcard interrupt service routine Restrictions:				 *****************************************************************************/cyg_uint32 isr_smc(cyg_vector_t vector,                   cyg_addrword_t data){	cyg_interrupt_mask(vector);//mask the smartcard interrrupt	cyg_interrupt_acknowledge(vector); //notify the cpu 	uart1_irsm_isc = regs0->uart1_irsm_isc;	uart1_isc = regs0->uart1_isc;	uart1_lsr = regs0->uart1_lsr;	/*handle the line erro interupt*/	if (uart1_isc & ISTATUS_LS) 	{		if (uart1_lsr & 0x80) 		{			overrun++;		}		goto exit;	}		/*handle the transmit interrupt*/	if (uart1_isc & ISTATUS_TX) 	{		if (uart1_lsr & ~UART_TX_RDY)		{			regs0->uart1_data = txBuf[txPtr++];			if (txPtr == txNum) 			{				txCompleted = 1;				regs0->uart1_isc &= ~ISC_TXM;				startTime = endTime = GET_TIME();				regs0->uart1_isc |= ISC_RXM;				startTimer(800);			}		}		goto exit;	}	/*handle the receive interrupt*/	if (uart1_isc & ISTATUS_RX) 	{		#if 0		endTime = GET_TIME();		if ((endTime -startTime) > 1000) 		{			regs0->uart1_isc &= ~ISC_RXM;			deviceStatus = 0;		}else {			startTime = endTime;		}		#endif		if (uart1_lsr & UART_RX_RDY)		{			startTimer(800);			rxBuf[rxPtr++] = regs0->uart1_data;			if (rxPtr == rxNum) 			{				stopTimer();				regs0->uart1_isc &= ~ISC_RXM;				regs0->uart1_isc &= ~ISC_LSM;				deviceStatus = 0;				rxCompleted = 1;							}		}		goto exit;	}	return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR);exit:	cyg_interrupt_unmask(SMC_VECTOR);	return (CYG_ISR_HANDLED);			}/****************************************************************************** Prototype: void dsr_smc(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) Parameters:	cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data Returns: no Description:	 	1. the smartcard service routine Restrictions:				 *****************************************************************************/void dsr_smc(cyg_vector_t vector,			cyg_ucount32 count,                  	cyg_addrword_t data){	/* handle the card insert */	if (uart1_irsm_isc & ISTATUS_SCII)	{								HAL_DELAY_US(1000*10); //delay 100 ms		if (regs0->uart1_sm_if & SM_PRES_CHK) 		{			restSmartCard();			readART();		}	}	/* handle the card absent*/	if (uart1_irsm_isc & ISTATUS_SCWI) 	{		memset(art, 0, artLen);		deviceStatus =0;		stopTimer();	}	cyg_interrupt_unmask(vector);}void smc_isr_install(void){	cyg_interrupt_create(SMC_VECTOR,					    0,					    0,					    &isr_smc,					    &dsr_smc,					    & int_smc_hd,					    &int_smc);	cyg_interrupt_attach(int_smc_hd);	cyg_interrupt_unmask(SMC_VECTOR);	}void smc_isr_uninstall(void){	cyg_interrupt_mask(SMC_VECTOR);	cyg_interrupt_detach(int_smc_hd);	cyg_interrupt_delete(int_smc_hd);}/****************************************************************************** Prototype: int startTransaction(UINT8 *pData, UINT8 txLen, UINT8 rxLen) Parameters:	pdata the data to send to the card 			txLen the number of the transmit data 			rxLen the number of the receive data Returns: 0 sucess , -1  false  Description:	 	1. send the data to the card , and revice the data from the card Restrictions:				 *****************************************************************************/int startTransaction(UINT8 *pData, UINT8 txLen, UINT8 rxLen){	short uart1_lsr;	if (!pData)	{		return -2;	}	if (deviceStatus) 	{		return 1;	}	//ecos_printf("startTransaction\n");	memcpy(txBuf, pData, txLen);	deviceStatus = 1;	txNum = txLen;	txPtr = 0;	rxNum = rxLen;	rxPtr = 0;	rxCompleted = 0;	txCompleted = 0;	uart1_lsr = regs0->uart1_lsr;	regs0->uart1_sm_ctrl |= SM_RX_RST|SM_TX_RST;	regs0->uart1_isc |= ISC_TXM|ISC_LSM;	isTimeout = 0;	return 0;}/****************************************************************************** Prototype:  int getSmcACK(UINT8 *pData, int num) Parameters:	pData  num the number of data to get			 num =-1 ,get the current revceive data Returns: > 0 number of the data to read 		-1 erro  		-2 the parameter erro 		 Description:	 	1. get the current status of the SMC interface device  Restrictions:				 *****************************************************************************/int getSmcACK(UINT8 *pData, int num){	if (pData == NULL)	{		return -2;	}	if ((num == -1)) 	{		memcpy(pData, rxBuf, rxPtr);		return rxPtr;	}#if 0		if (num > rxPtr) 	{		return -1;	} else {		memcpy(pData, rxBuf, num);		return num;			}#else	if(num > rxPtr)		num = rxPtr;	memcpy(pData, rxBuf, num);	return num;#endif}/****************************************************************************** Prototype:int querySmcStatus(void) Parameters:	no Returns: 0  the device is idel ,  		1 the device is wroking, 		2 the tx is not complted, 		3 the rx is not completed, 		4 revice a byte time out Description:	 	1. get the current status of the SMC interface device  Restrictions:				 *****************************************************************************/int querySmcStatus(void){	if (deviceStatus)	{		if (txCompleted && !rxCompleted) 		{			#if 0			endTime = GET_TIME();			if ((endTime-startTime) > 10000) 			{				deviceStatus = 0;				//regs0->uart1_isc &= ~ISC_RXM;				//regs0->uart1_isc &= ~ISC_LSM;				return 4;			}else {				return 3;			}			#endif			if (isTimeout)			{				deviceStatus = 0;				regs0->uart1_isc &= ~ISC_RXM;				regs0->uart1_isc &= ~ISC_LSM;				return 4;			}			return 3;		}else if (!txCompleted){			return 2;		}	}	return 0;}/****************************************************************************** Prototype:  int checkSMCPres(void) Parameters:	no Returns: 0 card absent,		1 card present 		 Description:	 	1. get the current status of the card  Restrictions:				 *****************************************************************************/int checkSMCPres(void){	 return(CARD_PRES());}/****************************************************************************** Prototype:  void  stopSmc(void) Parameters:	no Returns: no 		 Description:	 	1. stop smartcard interface device Restrictions:				 *****************************************************************************/void  stopSmc(void){	regs0->uart1_isc &= ~ISC_TXM & ~ISC_RXM & ~ISC_LSM;	deviceStatus = 0;	isTimeout = 0;	stopTimer();//	ecos_printf("*****stopSmc******\n");}static void handleTimeout(void){	isTimeout = 1;//	ecos_printf("*****line %d in %s timout******\n", __LINE__, __FILE__);}

⌨️ 快捷键说明

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