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

📄 drv_card.c

📁 CPU卡在税控行业应用驱动,符合7816要求
💻 C
📖 第 1 页 / 共 3 页
字号:
////////////////////////////////////////////////////////////////
// 文件名           :drv_card.c
// 版本             :Ver 1.0                            
// 目的及主要功能   :卡部分的驱动函数
// 作者             :
// 创建日期         :
// 修改者           :maquan                    
// 修改日期         :2005.02.10     
////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/termios.h>

#include "drv_time.h"
//#include "skj_comm.h"  //debug_step
//#include "skj_fun.h"   

void scc_set_extra_guardtime(unsigned int val);
void scc_set_paramfd(unsigned int f, unsigned int d);
int scc_set_protocol(int protocol);
unsigned char pts1;

#define NEW_CARD_MODE

#define SCC_STAT_UNRESET  0
#define SCC_STAT_RESETTED 1

#define  BUF_LEN 256
#define  WMI_TIMEOUT 4    //hhhh

#define MAX_CARD_NUM  2

#define SCCIODETECT   0x9900    /* Detect the SmartCard */
#define SCCIOCCLK     0x9901    /* enable or disable CLK signal */
#define SCCIOCPWR     0x9902    /* power up or power down */
#define SCCIOCRESET   0x9903    /* perform a RESET signal to card */
#define SCCIOCSBAUD   0x9904    /* set SCC baud rate */
#define SCCIOSPROTO   0x9905    /* set protocol */
#define SCCIOSEGTIME  0x9906    /* set Extra Guard time */
#define SCCIOSPARAMFD 0x9907    /* set parameter F & D */
#define SCCIOSELECT   0x9908    /* select the SmartCard device, specially */
#define SCCIODELAYUS  0x9909    /* Maybe some user need it */
#define SCCIOSCCMODE  0x990a    /* Set the mode into SCC mode */
#define SCCIOFLSFIFO  0x990b    /* flush fifo when find a bad card */

//===================================memcard ioctl opration symbles; 
#define MEMCARDIOCEN    0x23203800
#define MEMCARDIOCDIS   0x23203801
#define MEMCARDIOCRST   0x23203802
#define MEMCARDIOCSPOS  0x23203803
#define MEMCARDIOCGSTAT 0x23203804
#define MEMCARDIOCGSIZE 0x23203805
//#define SCCIOSELECT   0x9908
//==================================================================

#define MEMCARD "/dev/arca/memcard"  //mok1014
#define SMARTCARD "/dev/ttyUART0"

int scc_filedesc; // file descriptor for POSIX standard I/O operation 
int memcard_fd;   

struct scc_context {
    unsigned char slotnum;   /* slot number */
    unsigned char stat;      /* stat number */
    unsigned char protocol;  /* the supported protocol */

    /* extera_guardtime, scc_f & scc_d are parameters for
     * a particular card in a certain slot */
    unsigned int extra_guardtime;
    unsigned short scc_f;
    unsigned short scc_d;
    unsigned int baud;
};


//static struct scc_context cards[MAX_CARD_NUM] = {
//    {0, SCC_STAT_UNRESET, 0, 0, 0xffff, 0xffff, 9600},
//    {1, SCC_STAT_UNRESET, 0, 0, 0xffff, 0xffff, 9600},
//};
static struct scc_context cards[MAX_CARD_NUM] = {
    {0, SCC_STAT_UNRESET, 0, 0, 372, 1, 9600},
    {1, SCC_STAT_UNRESET, 0, 0, 372, 1, 9600},
};

/* The current active slot */
struct scc_context *current_slot = &cards[0];

static unsigned short ftable[16] = {
    0x7fff /*internal*/, 372, 558, 744, 1116, 1488, 1860, 0xffff /*RFU*/,
    0xffff /*RFU*/, 512, 768, 1024, 1536, 2048, 0xffff /*RFU*/, 0xffff/*RFU*/
};

/* WARNNING: n | 0x8000 means: 1/n, 0xffff is the value res for future,
 *           n | 0x8000 will be calculated in kernel driver, Please follow
 *           this rule. */
//static unsigned short dtable[16] = {
//    0xffff /*RFU*/, 1, 2, 4, 8, 16, 0xffff, 0xffff, 0xffff, 0xffff,
//    2 | 0x8000, 4 | 0x8000, 8 | 0x8000, 16 | 0x8000, 32 | 0x8000, 64 | 0x8000
//};
static unsigned short dtable[16] = {
    0xffff /*RFU*/, 1, 2, 4, 8, 16, 32, 0xffff, 12, 20,
    2 | 0x8000, 4 | 0x8000, 8 | 0x8000, 16 | 0x8000, 32 | 0x8000, 64 | 0x8000
};


//////////////////////////////////////////////////////////////////////
// Function name : scc_csum_check(uchar*,int)
// Version       : Ver 1.0
// Discriptions  : 
// Input value   : 
// Output value  : 
// Return value  : 
// Creater       : 
// Mender        : maquan
// Last date     : 2005.02.10
// Additional    : 
//////////////////////////////////////////////////////////////////////
//static int scc_csum_check(unsigned char *buf, int count)
int scc_csum_check(unsigned char *buf, int count)
{
    unsigned char csum = 0;
    int i;

    for (i=1;i<count;i++)
        csum ^= buf[i];

    if (csum == 0)
        return 0;

    return 1;
}


uint memcard_ini(void)
{
    if ((memcard_fd = open("/dev/arca/memcard", O_RDWR)) < 0)
    {
    //  lcd_disp(3,0,0,"打开memcard设备错误!");
    //  return;
        return 1;
    }
    return 0;
}


void memcard_fini(void)
{
    close(memcard_fd);
}


void memcard_reset(void)
{
    ioctl(memcard_fd, MEMCARDIOCRST, 0);  /* Reset the card */
}


void memcard_enable(void)
{
    ioctl(memcard_fd, MEMCARDIOCEN, 0);   /* Make the slot for a memory card */
}


void memcard_disable(void)
{
    ioctl(memcard_fd, MEMCARDIOCDIS, 0);
}


void memcard_set_pos(ulong pos)
{
    ioctl(memcard_fd, MEMCARDIOCSPOS, pos); /* Set the operation position */
}


void memcard_read(unsigned long offset, unsigned char *data, unsigned int length)
{
//  memcard_reset();
//  memcard_set_pos(0);
    memcard_set_pos(offset);
    read(memcard_fd, data, length);                                                                      //
}


void memcard_write(unsigned long offset,unsigned char *data,unsigned int length)
{
//  memcard_reset();
//  memcard_set_pos(0);
    memcard_set_pos(offset);
    write(memcard_fd, data, length);
}


//////////////////////////////////////////////////////////////////////
// Function name : card_ini(void)
// Version       : Ver 1.0
// Discriptions  : 
// Input value   : 
// Output value  : 
// Return value  : 0:成功,1
// Creater       : 
// Mender        : maquan
// Last date     : 2005.02.10
// Additional    : 
//////////////////////////////////////////////////////////////////////
int card_ini(void)
{
    struct termios tty;
    int cardnum = 0, testcount = 0;

    scc_filedesc = open(SMARTCARD, O_RDWR | O_NONBLOCK);
    if (scc_filedesc <=0 )
    {                                                                                              //
        //return CANNOT_OPEN_FILE_SCC;   //mok 0804
        return 1;
    }

    /* Use tty raw mode */

    tcgetattr(scc_filedesc, &tty);

    tty.c_iflag &= ~(IGNBRK | IGNCR | INLCR | ICRNL | IUCLC |
                      IXANY | IXON | IXOFF | INPCK | ISTRIP);
    tty.c_iflag |= (BRKINT | IGNPAR);
    tty.c_oflag &= ~OPOST;
    tty.c_lflag &= ~(XCASE|ECHONL|NOFLSH);
    tty.c_lflag &= ~(ICANON | ISIG | ECHO);
    tty.c_cflag |= CREAD;
    tty.c_cc[VTIME] = 5;
    tty.c_cc[VMIN] = 1;
    tcsetattr(scc_filedesc, TCSADRAIN, &tty);
    return 0;
}


void card_fini(void)
{
    close(scc_filedesc);
}


//////////////////////////////////////////////////////////////////////
// Function name : scc_select_slot(uchar)
// Version       : Ver 1.0
// Discriptions  : 
// Input value   : 
// Output value  : 
// Return value  : 
// Creater       : 
// Mender        : maquan
// Last date     : 2005.02.10
// Additional    : 
//////////////////////////////////////////////////////////////////////
int scc_select_slot(unsigned char slot)
{
    if (slot >= MAX_CARD_NUM)
    {
        //return OVER_MAX_CARD_NUM;     //mok 0804
        return 1;
    }

    slot = (slot+1)%2;

    current_slot = &cards[slot];
    ioctl(scc_filedesc, SCCIOSELECT, slot);

//  debug_step(03,current_slot->stat,slot);

    #if 1  //need to update kennel before open follow program?
    if(current_slot->stat == SCC_STAT_RESETTED)
    {
        scc_set_paramfd(current_slot->scc_f,current_slot->scc_d);
        scc_set_extra_guardtime(current_slot->extra_guardtime);
        scc_set_protocol(current_slot->protocol);
//      debug_step(02,current_slot->protocol,current_slot->scc_d);
    }
    else
    {
        scc_set_paramfd(current_slot->scc_f,current_slot->scc_d);
    }
    #endif
//  scc_set_paramfd(372,1);
    return 0;
}


//////////////////////////////////////////////////////////////////////
// Function name : scc_decode_atr(uchar)
// Version       : Ver 1.0
// Discriptions  : 
// Input value   : 
// Output value  : 
// Return value  : 
// Creater       : 
// Mender        : maquan
// Last date     : 2005.02.10
// Additional    : I only perform a basic decoding, some infos are not
//                 calculated.The currentSCC slot context is filled 
//////////////////////////////////////////////////////////////////////
void scc_decode_atr(unsigned char *str)
{
    int i = 2, j, p;
    int Y = (str[1] & 0xf0) >> 4;

    p = 1;

    current_slot->extra_guardtime = 0;//0629

    while (Y)
    {
        unsigned char Ynext;
        Ynext = 0;
        for (j=0;j<4;j++)
        {
            if (Y & 0x01)
            {
                switch (j)
                {
                    case 0:
                        current_slot->scc_f = ftable[(str[i] & 0xf0) >> 4];
                        current_slot->scc_d = dtable[(str[i] & 0x0f)];
                        pts1 = str[i];
//                      debug_step(04,current_slot->scc_d,(str[i] & 0x0f));
                        break;
                    case 1:
                        break;
                    case 2:
                        current_slot->extra_guardtime = str[i];
                        break;
                    case 3:
                        Ynext = (str[i] & 0xf0) >> 4;
                        current_slot->protocol = str[i] & 0x0f; /* protocol type */
                        break;
                }
                i++;
            }
            Y = Y >> 1;
        }
        break;           //mok0625
        Y = Ynext;
        p ++;
    }
}


void scc_udelay(unsigned int timeval)
{
    ioctl(scc_filedesc, SCCIODELAYUS, timeval);
}


void scc_clk_enable(void)
{
    ioctl(scc_filedesc, SCCIOCCLK, 1);
}


void scc_clk_disable(void)
{
    ioctl(scc_filedesc, SCCIOCCLK, 0);
}


void scc_poweron(void)
{
    ioctl(scc_filedesc, SCCIOCPWR, 1);
}


void scc_poweroff(void)
{
    ioctl(scc_filedesc, SCCIOCPWR, 0);
}


int scc_set_protocol(int protocol)
{
    if (protocol !=0 && protocol != 1)
    {
        return -1;
    }

    current_slot->protocol = protocol;
    ioctl(scc_filedesc, SCCIOSPROTO, protocol);
    return 0;
}


void scc_set_extra_guardtime(unsigned int val)
{
    current_slot->extra_guardtime = val;
    ioctl(scc_filedesc, SCCIOSEGTIME, val);
}


void scc_set_paramfd(unsigned int f, unsigned int d)
{
    if(f==0xffff || d==0xffff )
    {
        f = 372;
        d = 1;
    }
    current_slot->scc_f = f;
    current_slot->scc_d = d;
//  d=1;
    ioctl(scc_filedesc, SCCIOSPARAMFD,
          (((f << 16) & 0xffff0000) | (d & 0x0000ffff)));
//  ioctl(scc_filedesc, SCCIOSPARAMFD,
//  ((f/d)-1));
}


void scc_set_baud(unsigned int val)
{
    current_slot->baud = val;
    ioctl(scc_filedesc, SCCIOCSBAUD, val);
}


void scc_flush_fifo(void)
{
    ioctl(scc_filedesc, SCCIOFLSFIFO, 0);
}


void card_poweron(unsigned char slot)
{
    scc_select_slot(slot);
    scc_poweron();
}


void card_poweroff(unsigned char slot)
{
    scc_select_slot(slot);
    scc_poweroff();
}


//////////////////////////////////////////////////////////////////////
// Function name : check_atr_len(uchar*,uchar*)

⌨️ 快捷键说明

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