大学生
最后登录1970-1-1
在线时间 小时
注册时间2016-12-18
|
18火花
本帖最后由 qq5782098 于 2017-8-7 15:55 编辑
//起动总线
void Sle_Start(void)
{
SC_CLK_L();
SC_IO_H();
SC_CLK_H();
SysTick_Delay_Us(10);
SC_IO_L();
SysTick_Delay_Us(10);
SC_CLK_L();
SysTick_Delay_Us(10);
}
//结束总线
void Sle_Stop(void)
{
SC_IO_L();
SysTick_Delay_Us(10);
SC_CLK_H();
SysTick_Delay_Us(10);
SC_IO_H();
SysTick_Delay_Us(10); //发送起始信号
}
//复位和复位响应
//接收响应字节.
void Sle_Rst(void)
{
SC_RST_L();
SC_CLK_L();
SysTick_Delay_Us(10);
SC_RST_H();
SysTick_Delay_Us(10);
SC_CLK_H(); //clock maintain height 20US
SysTick_Delay_Us(20);
SC_CLK_L();
SysTick_Delay_Us(10);
SC_RST_L();
Sle_RD_Byte();//MRAM第一个字节,丢弃
Sle_RD_Byte();//第二个字节,同样丢弃,下同.
Sle_RD_Byte();
Sle_RD_Byte();
}
//得到复位响应
//buf:存储atr的指针
void Sle_Getatr(u8 *buf)
{
SC_RST_L()
SC_CLK_L()
SysTick_Delay_Us(10);
SC_RST_H()//产生复位时序
SysTick_Delay_Us(10);
SC_CLK_H()
SysTick_Delay_Us(20);
SC_CLK_L()
SysTick_Delay_Us(10);
SC_RST_L()
buf[0]=Sle_RD_Byte();//MRAM第一个字节,丢弃
buf[1]=Sle_RD_Byte();//第二个字节,同样丢弃,下同.
buf[2]=Sle_RD_Byte();
buf[3]=Sle_RD_Byte();
}
//向SLE写入一个字节
void Sle_WR_Byte (u8 x)
{
u8 i;
for(i=0;i<8;i++)
{
if(x&0x01)SC_IO_H()
else SC_IO_L()
SysTick_Delay_Us(10);
SC_CLK_H()
SysTick_Delay_Us(10);
SC_CLK_L()
x>>=1;
}
}
//从SLE读取一个字节
u8 Sle_RD_Byte (void)
{
u8 i,x;
x=0;
//SC_IO_L();
SC_IO_INT();//置数据线为输入方式
for(i=0;i<8;i++)
{
SC_CLK_L() //置时钟线为低准备接收数据位
SysTick_Delay_Us(10);
SC_CLK_H() //置时钟线为高使数据线上数据有效
SysTick_Delay_Us(10);
x>>=1;
if (SC_IO_READ())x|=0X80; //读数据位,接收的数据位放入x
}
SC_CLK_L()
SysTick_Delay_Us(10);
SC_IO_OUT();
return x;
}
//等待操作完成(内部处理模式)
//返回值:0,操作成功;其他,错误代码
u8 Sle_Wait(void)
{
u16 i=0;
SC_IO_INT();
SC_IO_L()
while(1)
{
i++;
SC_CLK_L()
SysTick_Delay_Us(10);
SC_CLK_H()
SysTick_Delay_Us(10);
if(SC_IO_READ())
{
SC_IO_OUT();
return 0;//内部处理模式已经完成了.
}
}
SC_IO_OUT();
return 1;//等待失败.
}
//中止操作
void Sle_Break(void)
{
SC_CLK_L()
SysTick_Delay_Us(10);
SC_CLK_H() //发出中止操作的时序
SysTick_Delay_Us(10);
SC_CLK_L()
}
//SLE写入命令+地址+数据
//cmd:指令
//addr:地址
//dat:数据
void Sle_WR_Cmd(u8 cmd,u8 addr,u8 dat)
{
Sle_Start(); //开始
Sle_WR_Byte(cmd); //发送命令
Sle_WR_Byte(addr); //写地址
Sle_WR_Byte(dat); //写数据
Sle_Stop(); //停止
}
//SLE指定地址读取指定长度的数据
//area:存储器范围
//addr:地址
//len:读取长度
//*buf:输出存放地址
void Sle_Read(u8 area, u8 addr, u8 len, u8*buf)
{
u8 i;
Sle_Rst();
Sle_WR_Cmd(area,addr,0);
for (i=0;i<len;i++) //读取数据
{
buf=Sle_RD_Byte();
}
}
//SLE指定地址开始写入指定长度的数据
//area:存储器范围
//addr:地址
//len:写入长度
//*buf:数据地址
//返回值:0,操作成功;其他,错误代码
u8 Sle_Write(u8 area,u8 addr,u8 len,u8 *buf)
{
u8 i,sta=0;
Sle_Rst();
for(i=0;i<len;i++)
{
Sle_WR_Cmd(area|0X08,addr+i,buf);//发送命令 0X38/0X39/0X3C 地址+数据
sta=Sle_Wait(); //发送操作脉冲
if(sta)break; //超时了
}
return sta;
}
//verify PSC code
//返回值:0,OK
// 1,只剩一次机会
// 2,废卡.
// 3,写入失败/密码错误.
u8 Sle_Ver_Psc(u8 *psc)
{
u8 ec;
Sle_Read(SLE_PSCR,0x00,1,&ec);//读取PSC数据
switch(ec&0x07)
{
case 1:return 1;
case 3:ec=1;break;
case 7:ec=3;break;
default: return 0X02;
}
Sle_Rst();
Sle_WR_Cmd(SLE_PSCR|0X08,0,ec);//回写EC字节
Sle_Wait(); //发送操作脉冲
Sle_WR_Cmd(SLE_PSC_CHK,1, 0xff);//校验码1
Sle_Wait(); //发送操作脉冲
Sle_WR_Cmd(SLE_PSC_CHK,2, 0xff);//校验码2
Sle_Wait(); //发送操作脉冲
Sle_WR_Cmd(SLE_PSC_CHK,3, 0xff);//校验码3
Sle_Wait(); //发送操作脉冲
Sle_WR_Cmd(SLE_PSCR|0X08,0,0XFF);//修改EC值
Sle_Wait(); //发送操作脉冲
ec=0;
Sle_Read(SLE_PSCR,0x00,1,&ec);//读取PSC数据
if((ec&0x07)!=0x07) return 0x03;//写入失败
return 0; //成功
}
void ATR_TEST(void)
{
Sle_Rst( );
}
//写入1个数据
u8 Test_Write(u8 area, u8 addr, u8 data)
{
return Sle_Write(area,addr,1,&data);//写入数据
}
//读取数据
u8 Test_Read(u8 area, u8 addr)
{
u8 ec;
Sle_Read(area,addr,1,&ec);
return ec;
}
|
|