📄 drv_card.c
字号:
////////////////////////////////////////////////////////////////
// 文件名 :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 + -