📄 card_pro.c
字号:
#include "include.h"
//sbit check_paper=P3^3;
sbit IC_CARD_IO=P4^1; //用户卡的I/O
sbit SAM_CARD_IO=P1^0; //SAM卡的I/O
#define BUZZ P1_1
#define MAXPAGE 2048 //flash card 最大页数
#define MAXBYTE 264 //flash card 每页最大字节数
#define RW_FLASH_CARD //是否编译FLASH CARD 的相关程序
/*********************定义FLASH CARD的硬件接口模式******************/
//#define SPI_MODE0 //select transmit mode
//#define SPI_MODE3
#define POLARITY_LOW
//#define POLARITY_HIGH
/*********************定义FLASH CARD的存储交换模式******************/
#define FLASH_BUFFER
//#define FLASH_PAGE
//#define FLASH_ARRAY //select read mode
/*******************选择FLASH CARD交换缓冲区*****************/
#define FLASH_BUFFER1 //select buffer1 or buffer2
#ifdef SPI_MODE0
#define ARRAY_READ_COM 0xe8 //直接阵列方式读主存储区数据
#define PAGE_READ_COM 0xd2 //直接页方式读主存储区数据
#define STATUS_READ_COM 0xd7 //读FLASH CARD 状态
#ifdef FLASH_BUFFER1
#define BUFFER_READ_COM 0xd4 //从FLASH CARD缓冲区读数据
#else
#define BUFFER_READ_COM 0xd6
#endif //FLASH_BUFFER1
#endif
#ifdef SPI_MODE3
#define HIGH
#define ARRAY_READ_COM 0xe8
#define PAGE_READ_COM 0xd2
#define STATUS_READ_COM 0xd7
#ifdef FLASH_BUFFER1
#define BUFFER_READ_COM 0xd4
#else
#define BUFFER_READ_COM 0xd6
#endif //FLASH_BUFFER1
#endif
#ifdef POLARITY_LOW
#define ARRAY_READ_COM 0x68
#define PAGE_READ_COM 0x52
#define STATUS_READ_COM 0x57
#ifdef FLASH_BUFFER1
#define BUFFER_READ_COM 0x54
#else
#define BUFFER_READ_COM 0x56
#endif //FLASH_BUFFER1
#endif
#ifdef POLARITY_HIGH
#define HIGH
#define ARRAY_READ_COM 0x68
#define PAGE_READ_COM 0x52
#define STATUS_READ_COM 0x57
#ifdef FLASH_BUFFER1
#define BUFFER_READ_COM 0x54
#else
#define BUFFER_READ_COM 0x56
#endif //FLASH_BUFFER1
#endif
#ifdef FLASH_BUFFER1
#define BUFFER_SECTOR_COM 0x53 //将主存储区读到FLASH CARD缓冲区
#define BUFFER_WRITE_COM 0x82 //写数据到FLASH CARD缓冲区
#define BUFFER_RWRITE_COM 0x58 //将FLASH CARD缓冲区数据写到主存储区
#define BUFFER_COMPARE_COM 0x60 //比较FLASH CARD缓冲区与主存储区的数据
#else
#define BUFFER_SECTOR_COM 0x55
#define BUFFER_WRITE_COM 0x85
#define BUFFER_RWRITE_COM 0x59
#define BUFFER_COMPARE_COM 0x61
#endif //FLASH_BUFFER1
sbit FLASH_CARD_CLK=P4^1; //flash clk
sbit FLASH_DO=P4^0; //flash out
//sbit FLASH_DI=PC^7; //flash in
//sbit FLASH_CARD_CS=cpld8 //FLASH_CARD_CS
uchar xdata cpu_t,cpu_ta1,cpu_d,cpu_tc1,cpu_tc2; //CPU CARD的复位应答特征数据
uchar xdata sam_t,sam_ta1,sam_d,sam_tc1,sam_tc2; //SAM CARD的复位应答特征数据
uchar bdata r_w_byte; //位变量,SPI,IIC总线使用
sbit HBIT=r_w_byte^7;
sbit LBIT=r_w_byte^0;
typedef union { uint word;
struct{uchar Hi;uchar Lo;} byte;
} UNST;
//===================================================================================
void En_cpu_clk(void)
{
PSD8xx_reg.PAGE|=0x20;
}
//===================================================================================
void Dis_cpu_clk(void)
{
PSD8xx_reg.PAGE&=0xdf;
}
//====================================================================================
void En_sam_clk(void)
{
PSD8xx_reg.PAGE|=0x10;
}
//====================================================================================
void Dis_sam_clk(void)
{
PSD8xx_reg.PAGE&= 0xef;
}
//=================================================================================
uchar rece_cpu_byte(void)
{
uchar i,j=4,m;
uint k;
//cpudata=0;
do
{
m=cpu_d; //等待起始位960 X CPU_D X CPU_TC2
do
{
i=cpu_tc2;
do
{
k=9600;
IC_CARD_IO=1;
do //10us
{
if(!IC_CARD_IO) break;
}while(--k);
if(!IC_CARD_IO) break;
}while(--i);
if(!IC_CARD_IO) break;
}while(--m);
if(!m)
return 1; //超时出错
delay_half_etu();
i=8;
do //读出8数据位
{
delay_etu();
if(cpu_t)
{
r_w_byte=r_w_byte>>1;
HBIT=IC_CARD_IO;
_nop_();
}
else
{
r_w_byte=r_w_byte<<1;
LBIT=IC_CARD_IO;
_nop_();
_nop_();
_nop_();
}
}while(--i);
delay_etu(); //接收奇偶校验码
if(!cpu_t)
r_w_byte=~r_w_byte;
ACC=r_w_byte;
PSW1=P; //ACC中1的个数 1为奇个数p=0
F0=IC_CARD_IO;
delay_half_etu();
if(PSW1)
{
if(F0) return 0;
}
else
{
if(!F0) return 0;
}
delay_half_etu();
IC_CARD_IO=0; //10.5 * etu发送错误信号
delay_etu();
delay_etu();
IC_CARD_IO=1;
}while(--j);
return 1;
}
//=====================================================================================
uchar send_cpu_byte(uchar send_data)
{
uchar i,j=4;
do
{
IC_CARD_IO=1;
delay_etu(); //字符间隔时间
delay_etu();
delay_etu();
delay_etu();
IC_CARD_IO=1;
if(!IC_CARD_IO) return 1;
if(cpu_tc1&&(cpu_tc1!=0xff))
{
i=cpu_tc1;
do
{
delay_half_etu();
delay_half_etu();
}while(--i);
}
IC_CARD_IO=0; //发送起始位
r_w_byte=send_data;
if(!cpu_t) r_w_byte=~r_w_byte;
i=8;
do
{
delay_etu();
if(cpu_t)
{
IC_CARD_IO=LBIT;
r_w_byte=r_w_byte>>1;
_nop_();
}
else
{
IC_CARD_IO=HBIT;
r_w_byte=r_w_byte<<1;
_nop_();
_nop_();
_nop_();
_nop_();
}
}while(--i);
delay_etu();
ACC=send_data;
_nop_();
_nop_();
IC_CARD_IO=P; //发送奇偶校验位
delay_etu();
r_w_byte=5;
while(--r_w_byte);
IC_CARD_IO=1; //检测错误信号
delay_etu();
r_w_byte=5;
while(--r_w_byte);
if(IC_CARD_IO) return 0; //11 * etu
delay_half_etu();
}while(--j);
return 1;
}
//===========================================================================
/*SAM CARD*/
uchar rece_sam_byte(void)//一位保持时间为372/foc ,foc=3,67M 时间为100us
{
uchar i,j=4,m;//firstbit;
uint k;
//samdata=0;
do
{
m=sam_d; //等待起始位960 X SAM_D X SAM_TC2
do
{
i=sam_tc2;
do
{
k=9600;
SAM_CARD_IO=1;
do //10us
{
if(!SAM_CARD_IO) break;
}while(--k);
if(!SAM_CARD_IO) break;
}while(--i);
if(!SAM_CARD_IO) break;
}while(--m);
if(!m){ return 1;} //超时出错
//delayms(1); //晶振不一样此地要调整
delay_half_etu();
i=8;
k=0;
do //读出8数据位
{
delay_etu();
if(sam_t)
{
//samdata=samdata>>1; //低位先传
r_w_byte=r_w_byte>>1;
HBIT=SAM_CARD_IO;
_nop_();
}
else
{
r_w_byte=r_w_byte<<1;
//if(SAM_CARD_IO)samdata|=0x01;
LBIT=SAM_CARD_IO;
_nop_();
// _nop_();
// _nop_();
}
}while(--i);
delay_etu(); //接收奇偶校验码
if(!sam_t)
r_w_byte=~r_w_byte;
ACC=r_w_byte;
PSW1=P;
F0=SAM_CARD_IO;
if(PSW1)
{
if(F0) return 0;
}
else
{
if(!F0) return 0;
}
delay_half_etu();
SAM_CARD_IO=0; //10.5 * etu发送错误信号
delay_etu();
SAM_CARD_IO=1;
}while(--j);
return 1;
}
//=====================================================================================
//卡的接收定时用
//在广州五所测试时加
void delay_etu1(void)
{
uchar i;
_nop_();
i=31;//104u
while(--i);
}
//===================================================================================
uchar send_sam_byte(uchar send_data)
{
uchar i,j=4;
do
{
SAM_CARD_IO=1;
delay_etu(); //字节间隔时间
delay_etu();
delay_etu();
delay_etu();
SAM_CARD_IO=1;
if(!SAM_CARD_IO) return 1;
if(sam_tc1&&(sam_tc1!=0xff))
{
i=sam_tc1;
do
{
delay_half_etu();
delay_half_etu();
}while(--i);
}
//////////////////////
EA=0;
SAM_CARD_IO=0; //发送起始位
r_w_byte=send_data;
if(!sam_t) r_w_byte=~r_w_byte;
i=8;
//广州五所 2 个 NOP
//_nop_();
//_nop_();
// _nop_();
do
{
//delay_etu(); //bit 的宽度
delay_etu1(); //bit 的宽度//在广州五所测试时加100us
if(sam_t)
{
SAM_CARD_IO=LBIT;
r_w_byte=r_w_byte>>1;
_nop_();
}
else
{
SAM_CARD_IO=HBIT;
r_w_byte=r_w_byte<<1;
_nop_();
}
}while(--i);
delay_etu1(); //在广州五所测试时加
ACC=send_data;
_nop_();
_nop_();
// _nop_();
SAM_CARD_IO=P; //发送奇偶校验位
delay_etu1(); //在广州五所测试时加
//_nop_();
// _nop_();
r_w_byte=5;
while(--r_w_byte);
SAM_CARD_IO=1; //检测错误信号
delay_etu();
r_w_byte=5;
while(--r_w_byte);
delay_half_etu(); //广州五所
if(SAM_CARD_IO) return 0; //11 * etu
delay_half_etu();
}while(--j);
return 1;
}
//=================================================================================
uchar atr_sam(uchar xdata *ptr)
{
uchar xdata i,temp,atr_len,error,cpu_tck=0,ti=0;
uchar xdata *p;
uint j=1000;
UNST bw;
//uchar xdata r_w_byte=0;
atr_len=0;
p=ptr;
bw.word=0;
card_vcc(1);//samcard_vcc(1);
sam_ta1=0x11,sam_d=1,sam_tc1=0,sam_tc2=10;
EA=0;
Writ_cpld(Sim_rst,0);//SAM_CARD_RST=0;
do //等待起始位
{
if(!SAM_CARD_IO)break;
}while(--j);
Writ_cpld(Sim_rst,1);//SAM_CARD_RST=1;
sam_t=1; //以正向协议传输
if(rece_sam_byte()) //TS
{
EA=1;
return 1; //非CPU卡
}
//else return 0; //暂时认为卡有数据响应为卡复位成功
if(r_w_byte==0x03) //反向传输
{
sam_t=0;
r_w_byte=0x3f;
}
else if(r_w_byte!=0x3b) //正向传输
{
EA=1;
return 1;//非CPU卡
}
*p=r_w_byte;
p++;
atr_len++;
error=rece_sam_byte(); //接收T0
if(error)
{
EA=1;
return 1;
}
*p=r_w_byte;
p++;
atr_len++;
bw.byte.Hi=r_w_byte&0x0f; //保存历史字节数据长度
if((r_w_byte&0x0f)>32) //历史字节数据超长出错
{
EA=1;
return 1;
}
atr_sam1:
temp=r_w_byte>>4;
i=4;
do //Td1...Tdi
{
if(temp&0x01)
{
error=rece_sam_byte();
if(error)
{
EA=1;
return 1;
}
*p=r_w_byte;
p++;
atr_len++;
if(atr_len==32) //数据超长出错
{
EA=1;
return 1;
}
if(i==4) //TAi
{
if(!ti) sam_ta1=r_w_byte; //TA1决定接收字符间最大时间
else if(ti==1) cpu_tck=1; //TA2...N表示有TCK校验
}
else if(i==2) //TCi
{
if(!ti) sam_tc1=r_w_byte; //TC1决定发送字符间最小时间
else if(ti==1) sam_tc2=r_w_byte; //TC2决定接收字符间最大时间
}
else if(i==1) //TDi---是否有TCK
{
if(r_w_byte&0x0f) cpu_tck=1; //TDi表示有TCK校验
ti++;
goto atr_sam1;
}
}
temp=temp>>1;
}while(--i);
if(bw.byte.Hi) //有历史数据
{
i=bw.byte.Hi;
bw.byte.Hi+=atr_len;
do //读出历史字节:T1...Tk
{
error=rece_sam_byte();
if(error)
{
bw.byte.Lo=error;
EA=1;
return bw.word;
}
*p=r_w_byte;
p++;
atr_len++;
if(atr_len==32) //数据超长出错
{
EA=1;
bw.byte.Lo=1;
return bw.word;
}
}while(--i);
}
else
bw.byte.Hi=atr_len;
if(cpu_tck) //有TCK校验
{
error=rece_sam_byte(); //读出TCK校验值
if(error)
{
bw.byte.Lo=error;
EA=1;
return bw.word;
}
*p=r_w_byte;
p++;
atr_len++;
temp=0; //TCK校验
for(i=1;i<atr_len;i++) temp^=ptr[i];
if(temp) //异或校验出错
{
EA=1;
bw.byte.Lo=1;
return bw.word;
}
}
if(!sam_tc2)
sam_tc2=10;
switch(sam_ta1&0x0f)
{
case 1:
sam_d=1;
break;
case 2:
sam_d=2;
break;
case 3:
sam_d=4;
break;
case 4:
sam_d=8;
break;
case 5:
sam_d=16;
break;
case 6:
sam_d=32;
break;
case 8:
sam_d=12;
break;
case 9:
sam_d=20;
break;
default:
break;
}
EA=1;
return bw.word;
}
//=====================================================================================
uchar Sam_Apdu(uchar xdata *out_buf,uchar xdata *in_buf)
{
uchar data ins;
uchar i,lc,le,lout,error,send_flag=0;
uchar xdata buf[10];
uchar xdata *out,*in;
uchar xdata **pp;
UNST bw;
EA=0;
card_vcc(1);
le=0;
lc=out_buf[4];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -