📄 iccard.b.c
字号:
}
else{ //读卡,Lc 不存在(-1)
while(1)
{ // receive one byte INS
rlt = EVOC_rev_one_byte(ptr,TIMEOUT_MAX_CYCLE,NOT_TS_BIT);
if (rlt<0)
{
*rec_len = 0;
return rlt; // time out err or parity err
}
if ( !(*ptr==0x60) )
{ //0x60 等待;
break;
}
}
if ( ( rec_buf[0]==INS )||( rec_buf[0]==(INS^0x01) ) )
{
if ( evoc_adpu_Le == 0 )
{
while(1)
{
rlt = EVOC_rev_one_byte(ptr,TIMEOUT_MAX_CYCLE,NOT_TS_BIT);
if ( rlt==TIMEROUT_ERR) return rlt; // time out exit
if ( rlt<0 )
{
*rec_len = 0;
return rlt; // parity err
}
ptr++;
(*rec_len)++;
if ( *rec_len >= 256 ) return 0;
}
}
else
{ // Le !=0 && !=-1 (因为Le和Lc不能同时为-1)
while(1)
{
rlt = EVOC_rev_one_byte(ptr,TIMEOUT_MAX_CYCLE,NOT_TS_BIT);
if (rlt<0)
{
*rec_len = 0;
return rlt; // time out err or parity err
}
ptr++;
(*rec_len)++;
if ( *rec_len >= evoc_adpu_Le+2 ) return 0;
}
}
}
else if( ( rec_buf[0]==(INS^0xff) )||( rec_buf[0]==(INS^0xfe) ) )
{
while(1)
{
rlt = EVOC_rev_one_byte(ptr,TIMEOUT_MAX_CYCLE,NOT_TS_BIT);
if ( rlt==TIMEROUT_ERR) return rlt; // time out exit
if ( rlt<0 )
{
*rec_len = 0;
return rlt; // parity err
}
ptr++;
(*rec_len)++;
if ( *rec_len >= 256 ) return 0;
}
}
else
{ // Sw1+ SW2, 收SW2
ptr++; //留下上一个收到的字节,是SW1
(*rec_len)++;
rlt = EVOC_rev_one_byte(ptr,TIMEOUT_MAX_CYCLE,NOT_TS_BIT);
if (rlt<0)
{
*rec_len = 0;
return rlt; // time out err or parity err
}
ptr++;
(*rec_len)++;
return 0;
}
}
}
//******************************************************
//******************************************************
static void enable_Time1(u_int32_t time_per)
{
u_int32_t tmod;
outl(time_per, S3C44B0X_TCNTB1);
s3c44b0x_unmask_irq(S3C44B0X_INTERRUPT_TIMER1);
tmod = inl(S3C44B0X_TCON);
tmod |= S3C44B0X_TCON_T1_START;
outl(tmod, S3C44B0X_TCON);
}
//******************************************************
//******************************************************
static void disable_Time1(void)
{
u_int32_t tmod;
s3c44b0x_mask_irq(S3C44B0X_INTERRUPT_TIMER1);
tmod = inl(S3C44B0X_TCON);
//tmod=0;
tmod &= ~(S3C44B0X_TCON_T1_START);
outl(tmod, S3C44B0X_TCON);
}
//*******************************************************
//*******************************************************
static void setup_timer (void)
{
__u32 rw_tmp;
u_int32_t tmod;
outl(0x778,S3C44B0X_TCNTB1);
tmod = inl(S3C44B0X_TCON);
//tmod=0;
tmod |= S3C44B0X_TCON_T1_MAN_UPDATE;
outl(tmod, S3C44B0X_TCON);
/* initialize the timer period and prescaler */
rw_tmp = inl(S3C44B0X_TCFG0);
rw_tmp &= ~(0xff<<0);
rw_tmp |= (1)<<0;
outl(rw_tmp, S3C44B0X_TCFG0); // prescaler = 1
rw_tmp = inl(S3C44B0X_TCFG1);
rw_tmp &= ~(0xf<<0);
rw_tmp |= 0<<0;
outl(rw_tmp, S3C44B0X_TCFG1); // mux = 1/2
//disable_Time1();
s3c44b0x_unmask_irq(S3C44B0X_INTERRUPT_TIMER1);
//tmod = inl(S3C44B0X_TCON);
//tmod=0;
//tmod |= S3C44B0X_TCON_T1_AUTO;
//tmod |= S3C44B0X_TCON_T1_START;
//outl(tmod, S3C44B0X_TCON);
outl(0x05, S3C44B0X_INTCON);
}
/*----------------------------------------------------------------------------*/
/* file_operations functions -------------------------------------------------*/
static ssize_t EVOC_iccard_write (struct file *file,
char *buff, /* the buffer to fill with data */
size_t len, /* the length of the buffer. */
loff_t *offset)
{ /* Our offset in the file */
int retval=0;
char txbuf[EVOC_ICCARD_BUF_SIZE];
if ((len>=sizeof(txbuf))||(len<=0)) return -EINVAL;
copy_from_user( txbuf, buff, len);
if (card_selected==SAMCARD) {
EVOC_select_sam();
delay_cycle(1000);
if (samcard_err<0) return -1;
}
else if(card_selected==USRCARD){
EVOC_select_usr();
delay_cycle(1000);
if (usrcard_err<0) return -1;
}
else return NO_SELECTED_CARD_ERR;
retval = EVOC_iccard_comm(txbuf,len,iccardfifo.buffer,&iccardfifo.len);
if (card_selected==SAMCARD) {
samcard_err = retval;
}
else if(card_selected==USRCARD){
usrcard_err = retval;
}
else return NO_SELECTED_CARD_ERR;
#ifdef DEBUG_ICCARD
EVOC_show_card_err_msg(retval);
#endif
return retval;
}
/*
* Called whenever a process attempts to read the device it has already open.
*/
static ssize_t EVOC_iccard_read (struct file *file,
char *buff, /* the buffer to fill with data */
size_t len, /* the length of the buffer. */
loff_t *offset)
{ /* Our offset in the file */
int retval = 0;
//sti();
if (iccardfifo.len==0) retval=0;
else
{
retval = iccardfifo.len;
if ( copy_to_user (buff, iccardfifo.buffer, iccardfifo.len) )
retval = -EFAULT;
}
iccardfifo.len = 0;
return retval;
}
/*
* Called whenever a process attempts to do an ioctl to the device it has
* already open.
*/
static int EVOC_iccard_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, /* the command to the ioctl */
unsigned long arg) { /* the parameter to it */
int retval=0;
char flag_test=0;
switch (cmd)
{
case EVOC_CARD_SELECT:
if ( arg == SAMCARD ) card_selected = SAMCARD;
else if ( arg == USRCARD ) card_selected = USRCARD;
else card_selected = NONECARD;
break;
case EVOC_CARD_RESET:
if ( card_selected == USRCARD )
if (usrcard_err == NO_CARD_ERR) return -1;
retval = EVOC_iccard_reset( iccardfifo.buffer, &iccardfifo.len, card_selected );
#ifdef DEBUG_ICCARD
EVOC_show_card_err_msg(retval);
#endif
return retval;
break;
case EVOC_CARD_STATUS:
if( card_selected == SAMCARD )
{
if ((retval = put_user(samcard_err, (int *)arg)) < 0)
return retval;
}
else if ( card_selected == USRCARD )
{
if ((retval = put_user(usrcard_err, (int *)arg)) < 0)
return retval;
}
else return -EINVAL;
break;
case EVOC_CARD_POWER_OFF:
if ( card_selected == SAMCARD ) EVOC_sam_card_release();
if ( card_selected == USRCARD ) EVOC_usr_card_release();
break;
case EVOC_USR_CARD_ERR:
printk("usrcard_err = %d\n",usrcard_err);
if ((retval = put_user(usrcard_err, (int *)arg)) < 0)
return retval;
break;
case EVOC_SAM_CARD_ERR:
printk("samcard_err = %d\n",samcard_err);
if ((retval = put_user(samcard_err, (int *)arg)) < 0)
return retval;
break;
case EVOC_START_TEST_ETU:
printk("start half etu time1\n");
enable_Time1(0x1fff);
EVOC_select_usr();
while(1)
{
if(flag_test==0)
{
flag_test=1;
CARD_TX_CLR;
}
else
{
flag_test=0;
CARD_TX_SET;
}
delay_half_etu();
}
break;
case EVOC_STOP_TEST_ETU:
printk("start one etu time1\n");
EVOC_select_sam();
while(1)
{
if(flag_test==0)
{
flag_test=1;
CARD_TX_CLR;
}
else
{
flag_test=0;
CARD_TX_SET;
}
delay_one_etu();
}
//disable_Time1();
break;
case EVOC_IC_PIN_TEST:
printk("IC_PIN_TEST\n");
switch (arg)
{
case SAM_SET_REST:
EVOC_sam_set_card_rst();
break;
case SAM_CLR_REST:
EVOC_sam_clr_card_rst();
break;
case USR_SET_REST:
EVOC_usr_set_card_rst();
break;
case USR_CLR_REST:
EVOC_usr_clr_card_rst();
break;
case SAM_POW_ON:
EVOC_sam_card_pwr_on();
break;
case SAM_POW_OFF:
EVOC_sam_card_pwr_off();
break;
case USR_POW_ON:
EVOC_usr_card_pwr_on();
break;
case USR_POW_OFF:
EVOC_usr_card_pwr_off();
break;
case LED_POW_ON:
EVOC_LED_ON();
break;
case LED_POW_OFF:
EVOC_LED_OFF();
break;
default:
break;
}
break;
default:
return -EINVAL;
break;
}
return 0;
}
/*
* Called whenever a process attempts to open the device file.
*/
static int EVOC_iccard_open(struct inode *inode, struct file *file) {
int err;
//int i;
//unsigned char b;
unsigned long flag;
if(iccard_device_open) return -EBUSY;
MOD_INC_USE_COUNT;
/* And my own counter too */
iccard_device_open++;
//EVOC_iccard_reset( iccardfifo.buffer, &iccardfifo.len, SAMCARD);
//#ifdef DEBUG_ICCARD
//printk("\nRead %d bytes from sam iccard reset: \n",iccardfifo.len);
//for (i=0;i<iccardfifo.len;i++)
//printk("nread=%d data=%x \n",i,iccardfifo.buffer[i]);
//#endif
//#ifdef DEBUG_ICCARD
//printk("\nRead %d bytes from usr iccard reset: \n",iccardfifo.len);
//for (i=0;i<iccardfifo.len;i++)
//printk("nread=%d data=%x \n",i,iccardfifo.buffer[i]);
//#endif
card_selected=NONECARD;
//init buffer
iccardfifo.len = 0;
EVOC_iccard_set_port();
// if (err<0) printk("open err\n");
#ifdef DEBUG_ICCARD
printk("iccard open ok\n");
#endif
err=request_irq(S3C44B0X_INTERRUPT_TIMER1,etu_time_handle,0,DEVICE_NAME,NULL);
if(err<0)
printk("%s: Error registering the device\n", __file__);
else
printk("%s: S3C44B0X_INTERRUPT_TIMER1 IRQ : %d\n",
__file__,S3C44B0X_INTERRUPT_TIMER1);
local_irq_save(flag);
//printk("%s: local_irq_save exis\n",__file__);
setup_timer();
//printk("%s: setup_time1\n",__file__);
local_irq_restore(flag);
//cli();
printk("time_flag11 = %d\n",time_flag);
//enable_Time1(0xfff);
//while(time_flag!=1);
printk("time_flag = %d\n",time_flag);
disable_Time1();
return 0; /* open succeed */
}
/*
* Called whenever a process attempts to close the device file.
*/
static int EVOC_iccard_release(struct inode *inode, struct file *file)
{
card_selected = NONECARD;
EVOC_sam_card_release();
EVOC_usr_card_release();
free_irq(S3C44B0X_INTERRUPT_TIMER1,NULL);
MOD_DEC_USE_COUNT;
/* And my own counter too */
iccard_device_open--;
return 0;
}
static struct file_operations iccard_fops = {
owner: THIS_MODULE,
read: EVOC_iccard_read,
ioctl: EVOC_iccard_ioctl,
open: EVOC_iccard_open,
release: EVOC_iccard_release,
write: EVOC_iccard_write,
};
/*
* miscdevice structure for misc driver registration.
*/
/*
* Initialize the driver.
*/
static int __init EVOC_iccard_init(void)
{
int err;
/* Register the misc device driver */
EVOC_iccard_set_port();
EVOC_sam_card_release();
EVOC_usr_card_release();
err = register_chrdev(IC_MAJOR,DEVICE_NAME,&iccard_fops);
if(err<0)
printk("%s: Error registering the device\n", __file__);
else
printk("%s: Device register with name: %s and number: %d %d\n",
__file__, DEVICE_NAME, IC_MAJOR, IC_MINOR);
#ifdef CONFIG_DEVFS_FS
devfs_ICraw=devfs_register(NULL,"iccard",
DEVFS_FL_DEFAULT,IC_MAJOR,IC_MINOR,
S_IFCHR|S_IRUSR|S_IWUSR,&iccard_fops,NULL);
#endif
printk("%s initialized\n",DEVICE_NAME);
return 0; /* A non zero value means that init_module failed */
}
/*
* Cleanup - undid whatever EVOCl03_init did.
*/
void EVOC_iccard_cleanup(void) {
/* IRQ have to be freed after the hardware is instructed not to interrupt
* the processor any more.
*/
#ifdef CONFIG_DEVFS_FS
devfs_unregister(devfs_ICraw);
#endif
unregister_chrdev(IC_MAJOR,DEVICE_NAME);
}
module_init(EVOC_iccard_init);
module_exit(EVOC_iccard_cleanup);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -