📄 smartcardinterfacedrv.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 + -