IC卡sle4442比较密码失败,可以读到主存储器和错误计数器

2019-08-14 07:02发布

//起动总线
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[i]=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[i]);//发送命令 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;
}

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。