 
//===========================      加密芯片 SMEC98SP 接口  ===========================//
#include "smec98sp.h"

#ifdef SMEC_CHIP

#include <string.h>
#include "afxdef.h"
#include "stm32f4xx_ll_gpio.h"

//SMEC98SP IIC驱动程序，IO口模拟IIC协议
#define IIC_NOACK         TRUE
#define IIC_ACK           FALSE
#define HIGHT             TRUE
#define LOW               FALSE

#define IIC_DELAYTIME     24			//bit位延时(实测最小22,可以稳定通讯)
#define ACKCHECKTIME      2000			//等待ACK超时时间
#define IIC_START_TIMES   500			//发送（START信号+地址字节） 的次数

//===========================      与SMEC98SP通讯的管脚定义      ===========================//
#define IIC_SCL_Pin 		LL_GPIO_PIN_8
#define IIC_SCL_GPIO_Port 	GPIOA
#define IIC_SCL_GPIO_Clock 	LL_AHB1_GRP1_PERIPH_GPIOA

#define IIC_SDA_Pin 		LL_GPIO_PIN_9
#define IIC_SDA_GPIO_Port 	GPIOC
#define IIC_SDA_GPIO_Clock 	LL_AHB1_GRP1_PERIPH_GPIOC

//===========================      I2C通讯相关      ===========================//
#if (1)

int initedFlag = 0;			// 初始化标志
#define IIC_ADDR	0x00	//对应SMEC98SP中地址

//---------------------------------------------------------
//函数介绍：模拟端口基本配置初始化
//---------------------------------------------------------
void SMEC_I2cInit(void)
{
	LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

	LL_GPIO_SetOutputPin(IIC_SCL_GPIO_Port, IIC_SCL_Pin);
	LL_GPIO_SetOutputPin(IIC_SDA_GPIO_Port, IIC_SDA_Pin);

	GPIO_InitStruct.Pin = IIC_SCL_Pin;
	GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
	GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
	GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
	GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
	LL_GPIO_Init(IIC_SCL_GPIO_Port, &GPIO_InitStruct);

	GPIO_InitStruct.Pin = IIC_SDA_Pin;
	GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
	GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
	GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
	GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
	LL_GPIO_Init(IIC_SDA_GPIO_Port, &GPIO_InitStruct);

	// GPIO_InitTypeDef GPIO_InitStructure;
	// GPIO_InitStructure.GPIO_Pin = IIC_SDA_PIN;
	// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//GPIO_Speed_2MHz;
	// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
	// GPIO_Init(IIC_PORT, &GPIO_InitStructure);

	// GPIO_InitStructure.GPIO_Pin = IIC_SCL_PIN;
	// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//GPIO_Speed_2MHz;
	// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//GPIO_Mode_Out_OD;//GPIO_Mode_Out_PP;
	// GPIO_Init(IIC_PORT, &GPIO_InitStructure);

	initedFlag = 0x5a5a;			// 初始化标志
}

//数据信号设为输入模式
void SdaInputMode(void)
{
	LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

	GPIO_InitStruct.Pin = IIC_SDA_Pin;
	GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
	GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
	GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
	GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
	LL_GPIO_Init(IIC_SDA_GPIO_Port, &GPIO_InitStruct);
	
	// GPIO_InitTypeDef  GPIO_InitStructure; 
	// GPIO_InitStructure.GPIO_Pin = IIC_SDA_PIN; 
	// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//GPIO_Speed_2MHz; 
	// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 
	// GPIO_Init(IIC_PORT, &GPIO_InitStructure); 

}

//数据信号设为输出模式
void SdaOutputMode(void)
{
	LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

	GPIO_InitStruct.Pin = IIC_SDA_Pin;
	GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
	GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
	GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
	GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
	LL_GPIO_Init(IIC_SDA_GPIO_Port, &GPIO_InitStruct);
	
	// GPIO_InitTypeDef  GPIO_InitStructure;
	// GPIO_InitStructure.GPIO_Pin = IIC_SDA_PIN; 
	// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//GPIO_Speed_2MHz; 
	// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
	// GPIO_Init(IIC_PORT, &GPIO_InitStructure); 
}

void IIC_Delay(unsigned int times)
{
	u16 loop;
	for(loop=0;loop<times;loop++)
	{
	}
}


//时钟信号输出高电平
void IIC_SetSclPin(void)
{
	LL_GPIO_SetOutputPin(IIC_SCL_GPIO_Port, IIC_SCL_Pin);
	//GPIO_WriteBit(IIC_PORT,IIC_SCL_PIN,Bit_SET);
}

//时钟信号输出低电平
void IIC_ClrSclPin(void)
{
	LL_GPIO_ResetOutputPin(IIC_SCL_GPIO_Port, IIC_SCL_Pin);
	//GPIO_WriteBit(IIC_PORT,IIC_SCL_PIN,Bit_RESET);
}

//数据信号输出高电平
void IIC_SetSdaPin(void)
{
	LL_GPIO_SetOutputPin(IIC_SDA_GPIO_Port, IIC_SDA_Pin);
	//GPIO_WriteBit(IIC_PORT,IIC_SDA_PIN,Bit_SET);
}

//数据信号输出低电平
void IIC_ClrSdaPin(void)
{
	LL_GPIO_ResetOutputPin(IIC_SDA_GPIO_Port, IIC_SDA_Pin);
	//GPIO_WriteBit(IIC_PORT,IIC_SDA_PIN,Bit_RESET);
}

//获取数据信号上的输入
u32 IIC_GetSdaStus(void)
{
	return LL_GPIO_IsInputPinSet(IIC_SDA_GPIO_Port, IIC_SDA_Pin);
	
	//return (bool)(GPIO_ReadInputDataBit(IIC_PORT,IIC_SDA_PIN));
}

//时钟信号输出HLow
void IIC_SetScl(_Bool HLow)
{
	HLow?IIC_SetSclPin():IIC_ClrSclPin();
}

//数据信号输出HLow
void IIC_SetSda(_Bool HLow)
{
	HLow?IIC_SetSdaPin():IIC_ClrSdaPin();
}

//---------------------------------------------------------
//函数介绍：i2c起始信号产生
//参数说明：
//			void
//返回值说明：
//			void
//---------------------------------------------------------
void IIC_Start(void)
{
	SdaOutputMode();

	IIC_SetSda(HIGHT);
	IIC_SetScl(HIGHT);
	IIC_Delay(IIC_DELAYTIME);
	IIC_SetSda(LOW);
	IIC_Delay(IIC_DELAYTIME);
	IIC_SetScl(LOW);
}

//--------------------------------------------------------- 
//函数介绍：i2c停止信号产生
//参数说明：
//			void
//返回值说明：
//			void
//---------------------------------------------------------
void IIC_Stop(void)
{
	SdaOutputMode();
	
	IIC_SetSda(LOW);
	IIC_SetScl(HIGHT);
	IIC_Delay(IIC_DELAYTIME);
	IIC_SetSda(HIGHT);
	IIC_Delay(IIC_DELAYTIME);
}

//---------------------------------------------------------
//函数名: i2c发送一个字节
//参数说明：
//			ucVal : 字节数据
//返回值说明：
//			0 - 成功
//          1 - 失败
//---------------------------------------------------------
_Bool IIC_Send(u8 ucVal)
{
	_Bool Ack;
	u16 AckLoop;
	u8 i;

	SdaOutputMode();

	for(i=0;i<8;i++)
	{
		IIC_SetScl(LOW);
		IIC_Delay(IIC_DELAYTIME);
		IIC_SetSda((ucVal & 0x80)?TRUE:FALSE);
		IIC_Delay(IIC_DELAYTIME);
		IIC_SetScl(HIGHT);
		IIC_Delay(IIC_DELAYTIME);
		IIC_Delay(IIC_DELAYTIME);
		ucVal<<= 1;
	}
	IIC_SetScl(LOW);
	SdaInputMode();

	IIC_Delay(IIC_DELAYTIME);
	IIC_Delay(IIC_DELAYTIME);
	IIC_SetScl(HIGHT);
	IIC_Delay(IIC_DELAYTIME);
	IIC_Delay(IIC_DELAYTIME);
	Ack = IIC_NOACK;

	for(AckLoop=0;AckLoop<ACKCHECKTIME;AckLoop++) //260us
	{
		if(IIC_GetSdaStus() == 0)
		{
			Ack = IIC_ACK;
			break;
		}
		IIC_Delay(IIC_DELAYTIME);
	}
	IIC_SetScl(LOW);
	return Ack;			//return success=0 / failure=1
}

//---------------------------------------------------------
//函数名: i2c读取一个字节
//参数说明：
//			bACK - 读取一个字节完成后, 设置SDA状态值
//返回值说明：
//			接收到的数据
//---------------------------------------------------------
u8 IIC_Read(_Bool bACK)
{
	u8 Data;
	u8 i;

	SdaInputMode();

	Data = 0;
	for(i=0;i<8;i++)
	{
		Data <<= 1;
		IIC_SetScl(LOW);
		IIC_Delay(IIC_DELAYTIME);
		IIC_Delay(IIC_DELAYTIME);
		IIC_Delay(IIC_DELAYTIME);
		IIC_SetScl(HIGHT);
		IIC_Delay(IIC_DELAYTIME);
		IIC_Delay(IIC_DELAYTIME);
		if(IIC_GetSdaStus() != 0)
		{
			Data |= 1;
		}
		else
		{
			Data &= 0xfe;
		}
	}

	IIC_SetScl(LOW);
	SdaOutputMode();

	IIC_Delay(IIC_DELAYTIME);
	IIC_SetSda(bACK);
	IIC_Delay(IIC_DELAYTIME);
	IIC_SetScl(HIGHT);
	IIC_Delay(IIC_DELAYTIME);
	IIC_Delay(IIC_DELAYTIME);
	IIC_SetScl(LOW);
	return Data;
}

//---------------------------------------------------------
//函数名: 读出1串数据
//参数说明：
//			addr - I2C地址
//			buf	 - 要读取数据缓冲区指针
//			len	 - 待读取长度
//返回值说明：
//			接收到的数据
//---------------------------------------------------------
_Bool IIC_ReadWithAddr(u8 addr, u8 *buf, u8 len)
{
	unsigned int i;
	i = IIC_START_TIMES;
	 
	if (initedFlag != 0x5a5a)
	{
		SMEC_I2cInit();			// 初始化
	}
	
	while (i) 
	{
		IIC_Start();
		if (IIC_Send(addr) == IIC_ACK) 
		{
			break;
		}
		
		if (--i == 0) 
		{
			return IIC_NOACK;
		}
	}
	
	for(i = 0; i < len -1 ; i++)
	{
		buf[i] = IIC_Read(IIC_ACK);
	}

	buf[i] = IIC_Read(IIC_NOACK);

	IIC_Stop();

	return IIC_ACK;
}

//---------------------------------------------------------
//函数名: 写入1串数据
//参数说明：
//			addr - I2C地址
//			buf	 - 要写入数据缓冲区指针
//			len	 - 待写入长度
//返回值说明：
//			接收到的数据
//---------------------------------------------------------
_Bool IIC_WriteWithAddr(u8 addr, u8 *buf, u8 len)
{
	unsigned int i;
	i = IIC_START_TIMES;

	if (initedFlag != 0x5a5a)
	{
		SMEC_I2cInit();			// 初始化
	}
	
	while (i) 
	{
		IIC_Start();
		if (IIC_Send(addr) == IIC_ACK)
		{
			break;
		}
		
		if (--i == 0) 
		{
			return IIC_NOACK;
		}
	}

	for(i = 0; i < len; i++)
	{
		if(IIC_Send(buf[i]))
		{
			return IIC_NOACK;
		}
	}

	IIC_Delay(IIC_DELAYTIME);
	IIC_Delay(IIC_DELAYTIME);

	IIC_Stop();

	return IIC_ACK;

}
#endif

		 
// 得到加密芯片软件版本号
// 返回值为0时,表示获取版本号失败.
u16 SMEC_GetVer(void)
{  
	u8 rst = 0;  
	u16 ver = 0;  
	u8 bBuf[128] = {0};   
	 
	
	bBuf[0] = 0x00;	//读版本号命令字
	bBuf[1] = 0x00;
	bBuf[2] = 0x00;
	bBuf[3] = 0x00;   

	rst = IIC_WriteWithAddr(IIC_ADDR & 0xFE, bBuf, 4);
	if (rst == 0)                     
	{ 
		rst = IIC_ReadWithAddr(IIC_ADDR | 0x1, bBuf, 2);   
	}  
 
	if (rst == 0) 
	{
		ver = (bBuf[0]<<8)|(bBuf[1]);
	}
	return ver;	 
}

//---------------------------------------------------------
//函数名: 获取加密芯片SMEC98SP的UID
//参数说明：
//			pUID - UID存放指针
//返回值说明：
//			0 - 成功
//			1 - 失败
//---------------------------------------------------------
#define UID_LEN		0x0C	

u8 SMEC_GetUid(u8 * pUID)
{ 
	u8 i = 0;
	u8 rst = 0; 
	u8 sum = 0;
	u8 bBuf[128] = {0};  
	u8 cnt0 = 0;
	u8 cnt255 = 0;
	
	if (pUID == NULL)
	{
		return 1;
	}
	
	bBuf[0] = 0x01;	//读UID命令字
	bBuf[1] = 0x00;
	bBuf[2] = 0x00;
	bBuf[3] = 0x00;   

	rst = IIC_WriteWithAddr(IIC_ADDR & 0xFE, bBuf, 4);
	if (rst == 0)                     
	{ 
		rst = IIC_ReadWithAddr(IIC_ADDR | 0x1, bBuf, (UID_LEN + 2));   
	}
	
	if (rst == 0)                     
	{
		for (i=0;i<(UID_LEN+2);i++)
		{// 校验和
			sum += bBuf[i];
		}
	}

	for (i = 2;i<(UID_LEN + 2);i++)
	{
		if (bBuf[i] == 0)
		{
			cnt0++;
		}
		if (bBuf[i] == 0xFF)
		{
			cnt255++;
		}
	}
 
	if ((rst == 0) &&
		(bBuf[0] == 0x81) &&	// 0x81 表示执行正确, 其他表示错误
		(sum == 0) &&			// 和校验
		(cnt0 != 12) &&			// 全0
		(cnt255 != 12) &&		// 全FF
		1 )
	{
		memcpy(pUID, bBuf + 2, UID_LEN);
	}
	else
	{
		rst = 1;
	}
	return rst;	 
}

//---------------------------------------------------------
//函数名: 获取加密芯片SMEC98SP的随机数
//参数说明：
//			pRandom - 随机数存放指针
//返回值说明：
//			0 - 成功
//			1 - 失败
//---------------------------------------------------------
u8 SMEC_GetRandom(u8 *pRandom, u8 bLen)
{ 	
	u8 i = 0; 
	u8 rst = 0; 
	u8 sum = 0; 
	u8 bBuf[128] = {0};  
	
	if ((pRandom == NULL) || (bLen > 124) || (bLen == 0))
	{
		return 1;
	}
	 
	bBuf[0] = 0x02;
	bBuf[1] = 0x00;
	bBuf[2] = 0x00;
	bBuf[3] = bLen ;   
	
	rst = IIC_WriteWithAddr(IIC_ADDR & 0xFE, bBuf, 4);
	
	if (rst == 0)                     
	{ 
		rst = IIC_ReadWithAddr(IIC_ADDR | 0x1, bBuf, (bLen+2));  
	}
	
	if (rst == 0)                     
	{
		for (i=0;i<(bLen+2);i++)
		{// 校验和
			sum += bBuf[i];
		}
	}
 
	if ((rst == 0) &&
		(bBuf[0] == 0x82) &&	// 0x82 表示执行正确, 其他表示错误
		(sum == 0) &&			// 和校验
		1 ) 
	{ 
		memcpy(pRandom, bBuf + 2, bLen);
	}
	else
	{
		rst = 1;
	}
 
	return rst;	  
}
    
//---------------------------------------------------------
//函数名: 读Flash
//参数说明：
//			pbData - 读取数据存放地址
//			bLen  -  读取的数据长度
//返回值说明：
//			0 - 成功
//			1 - 失败
//说明:
//---------------------------------------------------------
u8 SMEC_ReadFlash(u16 wAddr, u8 *pbData, u8 bLen)
{
	u8 i = 0; 
	u8 rst = 0; 
	u8 sum = 0; 
	u8 bBuf[128] = {0};  

	if ((pbData == NULL) || (bLen > 124) || (bLen == 0))
	{
		return 1;
	}
	 
	bBuf[0] = 0x03;		        
	bBuf[1] = (u8)(wAddr>>8);
	bBuf[2] = (u8) wAddr;
	bBuf[3] = bLen;	    		//需要读取数据长度
 
	rst = IIC_WriteWithAddr(IIC_ADDR & 0xFE, bBuf, 4);
	
	if (rst == 0)                     
	{ 
		rst = IIC_ReadWithAddr(IIC_ADDR | 0x1, bBuf, (bLen+2));  
	}
	
	if (rst == 0)                     
	{
		for (i=0;i<(bLen+2);i++)
		{// 校验和
			sum += bBuf[i];
		}
	}
 
	if ((rst == 0) &&
		(bBuf[0] == 0x83) &&	// 0x83 表示执行正确, 其他表示错误
		(sum == 0) &&			// 和校验
		1 ) 
	{ 
		memcpy(pbData, bBuf + 2, bLen); 
	}
	else
	{
		rst = 1;
	}
 
	return rst;	   
} 
  
//---------------------------------------------------------
//函数名: 擦擦Flash
//参数说明：
//			wAddr - 擦擦地址
//返回值说明：
//			0 - 成功
//			1 - 失败
//说明:
//---------------------------------------------------------
u8 SMEC_EraseFlash(u16 wAddr)
{
	u8 i = 0; 
	u8 rst = 0; 
	u8 sum = 0; 
	u8 bBuf[128] = {0};  
 
	 
	bBuf[0] = 0x04;		        
	bBuf[1] = (u8)(wAddr>>8);
	bBuf[2] = (u8) wAddr;
	bBuf[3] = 0x00;	    	 
 
	rst = IIC_WriteWithAddr(IIC_ADDR & 0xFE, bBuf, 4);
	
	if (rst == 0)                     
	{  
		rst = IIC_ReadWithAddr(IIC_ADDR | 0x1, bBuf, 2); 
	}
	
	if (rst == 0)                     
	{
		for (i=0;i<2;i++)
		{// 校验和
			sum += bBuf[i];
		}
	}
 
	if ((rst == 0) &&
		(bBuf[0] == 0x84) &&	// 0x84 表示执行正确, 其他表示错误
		(sum == 0) &&			// 和校验
		1 ) 
	{  
	}
	else
	{
		rst = 1;
	}
 
	return rst;	
} 
  
//---------------------------------------------------------
//函数名: 写Flash
//参数说明：
//			pbData - 写入数据存放地址
//			bLen  -  写入的数据长度
//返回值说明：
//			0 - 成功
//			1 - 失败
//说明:
//---------------------------------------------------------
u8 SMEC_WriteFlash(u16 wAddr, u8 *pbData, u8 bLen)
{
	u8 i = 0; 
	u8 rst = 0; 
	u8 sum = 0; 
	u8 bBuf[128] = {0};  

	if ((pbData == NULL) || (bLen > 124) || (bLen == 0))
	{
		return 1;
	} 

	bBuf[0] = 0x05;		       
	bBuf[1] = (u8)(wAddr>>8);
	bBuf[2] = (u8) wAddr;
	bBuf[3] = bLen;	    		//需要读取数据长度
	memcpy(&bBuf[4], pbData, bLen);
 
	rst = IIC_WriteWithAddr(IIC_ADDR & 0xFE, bBuf, bLen + 4);
	
	if (rst == 0)                     
	{  
		rst = IIC_ReadWithAddr(IIC_ADDR | 0x1, bBuf, 2); 
	}
	
	if (rst == 0)                     
	{
		for (i=0;i<2;i++)
		{// 校验和
			sum += bBuf[i];
		}
	}
 
	if ((rst == 0) &&
		(bBuf[0] == 0x85) &&	// 0x85 表示执行正确, 其他表示错误
		(sum == 0) &&			// 和校验
		1 ) 
	{  
	}
	else
	{
		rst = 1;
	}
 
	return rst;	   
}   

  
//---------------------------------------------------------
//函数名: 加密数据
//参数说明：
//			key - 加密因子	(0~127)
//			pbData - 写入数据存放地址
//			bLen  -  写入的数据长度
//返回值说明：
//			0 - 成功
//			1 - 失败
//说明:
//---------------------------------------------------------
u8 SMEC_EncryptionData(u8 key, u8 *pbData, u8 bLen)
{
	u8 i = 0;
	u8 rst = 0;
	u8 sum = 0;
	u8 bBuf[128] = {0};

	if ((pbData == NULL) || (key > 127)  || (bLen >= 124) || (bLen == 0))
	{
		return 1;
	}

	bBuf[0] = 0x06;
	bBuf[1] = 0x00;
	bBuf[2] = key;
	bBuf[3] = bLen;	    		//需要读取数据长度
	memcpy(&bBuf[4], pbData, bLen);

	sum = 0;
	for (i=0;i<(bLen+4);i++)
	{// 校验和
		sum += bBuf[i];
	}
	bBuf[1] = 0 - sum;

	rst = IIC_WriteWithAddr(IIC_ADDR & 0xFE, bBuf, bLen + 4);

	if (rst == 0)
	{
		rst = IIC_ReadWithAddr(IIC_ADDR | 0x1, bBuf, (bLen+2));
	}

	if (rst == 0)
	{
		sum = 0;
		for (i=0;i<(bLen+2);i++)
		{// 校验和
			sum += bBuf[i];
		}
	}

	if (rst == 0)
	{
		if (sum != 0)
		{
			rst |= 4;
		}
		else if (bBuf[0] != 0x86)
		{
			rst = bBuf[0];
		}
	}

	if (rst == 0)
	{
		memcpy(pbData, bBuf + 2, bLen);
	}

	return rst;
}

//---------------------------------------------------------
//函数名: 解密数据
//参数说明：
//			key - 加密因子	(0~127)
//			pbData - 写入数据存放地址
//			bLen  -  写入的数据长度
//返回值说明：
//			0 - 成功
//			1 - 失败
//说明:
//---------------------------------------------------------
u8 SMEC_DecryptionData(u8 key, u8 *pbData, u8 bLen)
{
	u8 i = 0; 
	u8 rst = 0; 
	u8 sum = 0; 
	u8 bBuf[128] = {0};  

	if ((pbData == NULL) || (key > 127)  || (bLen >= 124) || (bLen == 0))
	{
		return 1;
	} 

	bBuf[0] = 0x07;
	bBuf[1] = 0x00;
	bBuf[2] = key;
	bBuf[3] = bLen;	    		//需要读取数据长度
	memcpy(&bBuf[4], pbData, bLen);
	
	sum = 0;
	for (i=0;i<(bLen+4);i++)
	{// 校验和
		sum += bBuf[i];
	}
	bBuf[1] = 0 - sum;

	rst = IIC_WriteWithAddr(IIC_ADDR & 0xFE, bBuf, bLen + 4);
	
	if (rst == 0)                     
	{   
		rst = IIC_ReadWithAddr(IIC_ADDR | 0x1, bBuf, (bLen+2)); 
	}
	
	if (rst == 0)                     
	{
		sum = 0;
		for (i=0;i<(bLen+2);i++)
		{// 校验和
			sum += bBuf[i];
		}
	}

	if (rst == 0)
	{
		if (sum != 0)
		{
			rst |= 4;
		}
		else if (bBuf[0] != 0x87)
		{
			rst = bBuf[0];
		}
	}
 
	if (rst == 0)
	{  
		memcpy(pbData, bBuf + 2, bLen); 
	}
 
	return rst;	   
}   

// 加密芯片验证
int SMEC_Detection(void)
{
	int rslt = 0;
	u8 dat1[12] = {0};
	u8 dat2[12] = {0};

	rslt = SMEC_GetUid(dat1);

	if (rslt == 0)
	{
		rslt = SMEC_GetRandom(dat1,12);
	}

	if (rslt == 0)
	{
		memcpy(dat2, dat1, 12);
		rslt = SMEC_EncryptionData(0, dat2, 12);
	}

	if (rslt == 0)
	{
		rslt = SMEC_DecryptionData(0, dat2, 12);
	}

	if (rslt == 0)
	{
		for (int i=0;i<12;i++)
		{
			if (dat2[i] != dat1[i])
			{
				rslt = 1;
			}
		}
	}
	return rslt;
}

#endif

