⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 esam_function.c

📁 DSP开发可以用来看外设情况的程序
💻 C
📖 第 1 页 / 共 3 页
字号:

/****************************************************************/
/*	文件名:		Esam_Function.c 								*/
/* 	功能:		定义ESAM卡的操作函数 							*/
/*  设计者:		陈湘和											*/
/*  设计日期:	10/20/2004										*/
/*--------------------------------------------------------------*/
/*  说明:														*/
/*  			该文件设计了通过DSP的UART操作ESAM卡进行数据保护 */
/*				的所有相关指令,这些指令是基于T=0协议设计的,如果 */
/* 				用户的ESAM芯片基于T=1协议,请在使用这些函数前用	*/
/*				读写器或者在通过认证后用Set_Protocol指令将ESAM	*/
/*				芯片的协议改为T=0.								*/
/****************************************************************/

#include <stdio.h>
#include <csl.h>
#include "Uart_Function.h"
#include "DEC5502_DES.h"
#include "DEC5502_MAC.h"

/* 定义两个宏来访问系统控制寄存器 */
#define SYSCNTL1 (*(volatile int *)(0x280000))
#define SYSCNTL2 (*(volatile int *)(0x280001))

#define DES8			0
#define DES16			1
#define RSTTIME			0xAD6B		// RST信号低电平时间长度取500个时钟周期							
#define MAXDATA			0xA7		// 一次最多能够读写167个数据	
									
#define DATALENGTH		MAXDATA+7	// 接收命令缓冲区最大长度 = 
									// MAXDATA+1字节数据位+4字节MAC码+2字节状态位
						
Uint16 CommandLength;				// 定义命令报文的实际长度变量						
Uint16 Command[DATALENGTH];			// 定义存放命令报文的缓冲区,为了初始化方便
									// 长度设为与接收缓冲区长度一致	

Uint16 ReplyData[DATALENGTH];		// 定义接收信号缓冲区

		
extern Uint16 Get_Random(Uint16 *OutputPtr, Uint16 Length);	

/****************************************************************/
/*	函数名:		Reset_Esam() 									*/
/* 	功能:		对ESAM卡复位,并取得返回的复位应答信息			*/
/*	参数:														*/
/*				DataPtr----指向存放序列号的数组的指针			*/
/*  返回值:														*/
/*              返回unsigned short int型的16bits整数  			*/
/*				如果正确,返回值等于9000							*/
/****************************************************************/
extern Uint16 Reset_Esam(Uint16 *DataPtr)
{
	Uint16 i,FeedValue;
	
	/* 初始化接收ESAM卡应答信号的数据结构 */
    for(i=0; i<DATALENGTH; i++)
    {
    	ReplyData[i] = 0;
    }
    
	/* RST信号变为低电平 */
    SYSCNTL2 = 0x00;
    Delay_Time(200);
    
	/* 将ESAM卡的I/O端设为输出,准备从ESAM卡接收复位应答信号 */
    SYSCNTL1 = 0x20;		
    Delay_Time(200);

    	
	/* 让复位信号等待一段时间,满足复位时序要求 */
	Delay_Time(RSTTIME);

	/* 让ESAM脱离复位状态,从而实现ESAM复位 */
	SYSCNTL2 = 0x08;
	
	/* 读复位应答信号 */
	Read_Esam(ReplyData,13);	
	
	/* 从复位应答信号中分离出序列号 */
   	for(i=0; i<8; i++)
   	{
   		*DataPtr++ = ReplyData[i+5];
   	}
	
	/* 获取状态字 */
   	FeedValue = 0x9000;
	return FeedValue;
}

/****************************************************************/
/*	函数名:		Get_Response() 									*/
/* 	功能:		取回ESAM反馈的数据和MAC码						*/
/*	参数:														*/
/*				DataPtr-----指向存放返回数据指针数组的指针		*/
/*				DataLen-----欲取回的数据和MAC码总长度(以16进制	*/
/*							表示,单字节长度)					*/
/*  返回值:														*/
/*              返回unsigned short int型的16bits整数  			*/
/*				如果正确,返回值等于9000							*/
/****************************************************************/
extern Uint16 Get_Response(Uint16* DataPtr, Uint16 DataLen)
{
	Uint16 i,State;
	
	/* 清空命令缓冲区和接收数据缓冲区 */
    for(i=0; i<DATALENGTH; i++)
    {
    	Command[i] = 0;
    }
    
    /* 填写接收返回数据的命令报文 */
	CommandLength = 5;
	
	Command[0] = 0x00;
	Command[1] = 0xC0;
	Command[2] = 0x00;
	Command[3] = 0x00;
	Command[4] = DataLen;	
	
	/* 将ESAM卡的I/O端设为输入,准备向ESAM卡发接收返回数据命令 */
    SYSCNTL1 = 0x60;		
    Delay_Time(200);
    
    /* 向ESAM卡发接收返回数据命令 */
    Write_Esam();
    
    /* 将ESAM卡的I/O端设为输出,准备从ESAM卡接收返回信息 */
    SYSCNTL1 = 0x20;		
    Delay_Time(200);
    
    /* 先清除接收缓冲区 */
    i = UART_RGET(URRBR);
	
	/* 取出ESAM反馈的命令报文中的第二个字节,丢弃 */
    while(!UART_FGET(URLSR,DR));
    i = UART_RGET(URRBR);
    
	/* 获取返回信息 */
	Read_Esam(ReplyData,DataLen+2);
	
	/* 从返回信息中分离出数据和MAC码 */
	for(i=0; i<DataLen; i++)
	{
		*DataPtr++ = ReplyData[i];
	}
	
	/* 获取状态字 */
   	State = (ReplyData[DataLen]<<8)|ReplyData[DataLen+1];
	return State;
}

/****************************************************************/
/*	函数名:		Del_Direct() 									*/
/* 	功能:		删除以前建立的目录文件(不包括MF文件)			*/
/*  参数:														*/
/*				无												*/
/*  返回值:														*/
/*              返回unsigned short int型的16bits整数  			*/
/*				如果正确,返回值等于9000							*/
/****************************************************************/
extern Uint16 Del_Direct(void)
{
	Uint16 i,State;
	
	/* 清空命令缓冲区 */
    for(i=0; i<DATALENGTH; i++)
    {
    	Command[i] = 0;
    }
    
    /* 填写删除目录的命令报文 */
	CommandLength = 5;
	
	Command[0] = 0x80;
	Command[1] = 0x0E;
	Command[2] = 0x00;
	Command[3] = 0x00;
	Command[4] = 0x00;	
	
	/* 将ESAM卡的I/O端设为输入,准备向ESAM卡发删除目录命令 */
    SYSCNTL1 = 0x60;		
    Delay_Time(200);
    
    /* 向ESAM卡发删除目录命令 */
    Write_Esam();
    
    /* 将ESAM卡的I/O端设为输出,准备从ESAM卡接收返回信息 */
    SYSCNTL1 = 0x20;		
    Delay_Time(200);
    
    /* 先清除接收缓冲区 */
    i = UART_RGET(URRBR);
	
	/* 获取返回信息 */
	Read_Esam(ReplyData,2);
	
	/* 获取状态字 */
   	State = (ReplyData[0]<<8)|ReplyData[1];
	return State;
}

/****************************************************************/
/*	函数名:		Create_Keyfile() 								*/
/* 	功能:		建立密钥文件									*/
/*	参数:														*/
/*				FileID-----2字节长度的文件标识符				*/
/*				FileLen----2字节长度的文件空间大小				*/
/*				IncRight---增加密钥权限							*/
/*  返回值:														*/
/*              返回unsigned short int型的16bits整数  			*/
/*				如果正确,返回值等于9000							*/
/****************************************************************/
extern Uint16 Create_Keyfile(Uint16 FileID, Uint16 FileLen, Uint16 IncRight)
{
	Uint16 i,State;
	
	/* 清空命令缓冲区和接收返回信息的数据结构 */
    for(i=0; i<DATALENGTH; i++)
    {
    	ReplyData[i] = 0;
    	Command[i] = 0;
    }
    
   /* 第一次发送创建Key文件的命令头,如果正确,应该返回0xE0 */
	CommandLength = 5;
	
	Command[0] = 0x80;			// 填写命令报文的头域
	Command[1] = 0xE0;
	Command[2] = (FileID&0xFF00)>>8;
	Command[3] = FileID&0x00FF;
	Command[4] = 0x07;
	
	/* 将ESAM卡的I/O端设为输入,准备向ESAM卡发创建Key文件命令 */
    SYSCNTL1 = 0x60;		
    Delay_Time(200);
    
    /* 发送创建Key文件命令的命令头域 */
	Write_Esam();
	
	/* 将ESAM卡的I/O端设为输出,准备从ESAM卡接收返回状态 */
    SYSCNTL1 = 0x20;		
    Delay_Time(200);

    /* 读空接收缓冲区 */
    i = UART_RGET(URRBR);
    
    /* 读返回的状态信号,以确定创建Key文件操作是否正确 */
	Read_Esam(ReplyData,1);
	
	/* 第二次发送创建Key文件命令的数据域,如果正确,应该返回状态9000 */
	CommandLength = 7;
	
	Command[0] = 0x3F;			// 填写命令报文的数据域
	Command[1] = (FileLen&0xFF00)>>8;
	Command[2] = FileLen&0x00FF;
    Command[3] = 0xFF;
    Command[4] = IncRight;
    Command[5] = 0xFF;
    Command[6] = 0xFF;
    
    /* 将ESAM卡的I/O端设为输入,准备向ESAM卡发送创建Key文件命令的数据域 */
    SYSCNTL1 = 0x60;		
    Delay_Time(200);
   	
    /* 向ESAM卡发创建Key文件命令的数据域 */
    Write_Esam();
    
    /* 将ESAM卡的I/O端设为输出,准备从ESAM卡接收返回状态 */
    SYSCNTL1 = 0x20;		
    Delay_Time(200);
    
    /* 读空接收缓冲区 */
    i = UART_RGET(URRBR);
    
    /* 读返回的状态信号,以确定创建Key文件操作是否正确 */
	Read_Esam(ReplyData,2);
	
	/* 获取状态字 */
   	State = (ReplyData[0]<<8)|ReplyData[1];
	return State;
}

/****************************************************************/
/*	函数名:		Increase_Key() 									*/
/* 	功能:		建立(39-外部认证/主控或36-线路保护)密钥			*/
/*	参数:														*/
/*				KeyID----- 密钥标识符							*/
/*				KeyType----密钥类型(0x39或0x36)					*/
/*				UseRight---密钥使用权							*/
/*				AltRight---密钥更改权限							*/
/*     			NextState--后续状态(如果密钥类型0x36保留为0xFF) */
/*				ErrCount---错误计数器							*/
/*				Keys-------指向存放欲建立密钥的数组的指针		*/
/*				Mode-------加解密密钥方式(如果是8字节密钥选		*/
/*						   DES8=0;否则为16字节密钥选DES16=1)	*/
/*  返回值:														*/
/*              返回unsigned short int型的16bits整数  			*/
/*				如果正确,返回值等于9000							*/
/****************************************************************/
extern Uint16 Increase_Key(Uint16 KeyID, Uint16 KeyType, Uint16 UseRight, Uint16 AltRight, Uint16 NextState, Uint16 ErrCount, Uint16 *Keys,Uint16 Mode)
{
	
	Uint16 i,State,KeyLen;
	
	/* 清空命令缓冲区和接收返回信息的数据结构 */
    for(i=0; i<DATALENGTH; i++)
    {
    	ReplyData[i] = 0;
    	Command[i] = 0;
    }
    
    if(Mode == DES8)
    KeyLen = 8;	
    else
    KeyLen = 16;
    
   /* 第一次发送创建Key的命令头,如果正确,应该返回0xD4 */
	CommandLength = 5;
	
	Command[0] = 0x80;			// 填写命令报文的头域
	Command[1] = 0xD4;
	Command[2] = 0x01;
	Command[3] = KeyID;
	Command[4] = KeyLen+5;
	
	/* 将ESAM卡的I/O端设为输入,准备向ESAM卡发创建Key命令 */
    SYSCNTL1 = 0x60;		
    Delay_Time(200);
    
    /* 发送创建Key命令的命令头域 */
	Write_Esam();
	
	/* 将ESAM卡的I/O端设为输出,准备从ESAM卡接收返回状态 */
    SYSCNTL1 = 0x20;		
    Delay_Time(200);

    /* 读空接收缓冲区 */
    i = UART_RGET(URRBR);
    
    /* 读返回的状态信号,以确定创建Key操作是否正确 */
	Read_Esam(ReplyData,1);
	
	/* 第二次发送创建Key命令的数据域,如果正确,应该返回状态9000 */
	CommandLength = KeyLen+5;
	
	Command[0] = KeyType;			// 填写命令报文的数据域
	Command[1] = UseRight;
	Command[2] = AltRight;
	
	if(KeyType == 0x39)				// 如果是外部认证密钥,有后续状态
	Command[3] = NextState;
	else							// 如果是线路保护密钥,该域保留为0xFF
    Command[3] = 0xFF;
    
    Command[4] = ErrCount;
    for(i=0; i<KeyLen; i++)
    {
    	Command[5+i] = *Keys++;
    }
    
    /* 将ESAM卡的I/O端设为输入,准备向ESAM卡发送创建Key命令的数据域 */
    SYSCNTL1 = 0x60;		
    Delay_Time(200);
   	
    /* 向ESAM卡发创建Key命令的数据域 */
    Write_Esam();
    
    /* 将ESAM卡的I/O端设为输出,准备从ESAM卡接收返回状态 */
    SYSCNTL1 = 0x20;		
    Delay_Time(200);
    
    /* 读空接收缓冲区 */
    i = UART_RGET(URRBR);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -