C++例程:使用其I/O模拟IIC接扣(2)
一)rjgt102_i2c.h
//版保芯片的I2C接口硬件抽象层
#ifndef __RJGT102_I2C_H__
#define __RJGT102_I2C_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
//I2C驱动结构体
typedef struct I2C_DRIVER
{
void (*Open)(void);
void (*ReadByte)(uint8_t *pByteData, uint8_t AddrToRead);
void (*WriteByte)(uint8_t ByteData, uint8_t AddrToWrite);
void (*Read)(uint8_t AddrToRead, uint8_t *pData, uint16_t Length);
void (*Write)(uint8_t AddrToWrite, uint8_t *pData, uint16_t Length);
void (*Close)(void);
} I2C_Driver_t;
#ifdef __cplusplus
}
#endif
#endif /* end of __RJGT102_I2C_H__ */
二)rjgt102.h
/**
**************************************************************************************
* Copyright(c) 2015 Wuhan Runjet, All rights reserved.
**************************************************************************************
* @file rjgt102.h
* @author Wuhan Runjet software and test team
* @date 04-Feb-2015
* @version V1.00
* @brief Header file for RJGT102 chip.
**************************************************************************************
*
*/
#ifndef __RJGT102_H__
#define __RJGT102_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "rjgt102_i2c.h"
/**
* @brief 杂项宏定义
*/
#define RJGT102_I2C_ADDR ((uint8_t)0x68) /*!< 芯片I2C接口地址 */
#define RJGT102_VERSION ((uint32_t)0x71843032); /*!< 芯片版本号 */
#define RJGT102_WATCHDOG_CLK ((uint32_t)3500000) /*!< 芯片看门狗时钟:3.5MHz */
#define REGIONAL_PROTECTION_CODE ((uint8_t)0x5A) /*!< 区域保护码 */
#define CMD_EXECUTION_TIMEOUT ((uint32_t)0xF0000); /*!< 命令执行的超时周期(必要时可改) */
/**
* @brief 命令执行状态
*/
typedef enum
{
ES_NORMAL = 0x01,
ES_OPERATING = 0x00,
ES_ERROR = 0x11,
ES_INVALID = 0x10,
ES_TIMEOUT = 0xFF
} ExecutionStatus_t;
/**
* @brief 读PAGE时的输出模式
*/
typedef enum
{
PAGE_ENCRYPT_OUTPUT = 0x00,
PAGE_DIRECT_OUTPUT = !PAGE_ENCRYPT_OUTPUT
} PageOutputMode_t;
/**
* @brief 看门狗控制
*/
typedef enum
{
WDG_DISABLE = 0,
WDG_ENABLE = !WDG_DISABLE
} WDG_CtrlState_t;
/**
* @brief 看门狗复位信号极性
*/
typedef enum
{
LOW_VALID = 0,
HIGH_VALID = !LOW_VALID
} WDG_RstPolarity_t;
/*** @brief 功能命令 ###################################################################
*/
#define CMD_INITUSID ((uint8_t)0xAA) /*!< 初始化用户ID命令 */
#define CMD_INITPAGE ((uint8_t)0xA5) /*!< 初始化PAGE命令 */
#define CMD_INITKEY ((uint8_t)0x5A) /*!< 初始化KEY命令 */
#define CMD_AUTHENTICATION ((uint8_t)0x55) /*!< 认证设备命令 */
#define CMD_READ ((uint8_t)0x0F) /*!< 读命令 */
#define CMD_WRITE ((uint8_t)0xF0) /*!< 写命令 */
#define CMD_GENERATEKEY ((uint8_t)0x33) /*!< 更新KEY命令 */
#define CMD_CLEARCMD ((uint8_t)0x00) /*!< 清命令寄存器命令 */
/*** @brief 寄存器定义 #################################################################
*/
#define REG_PAGE0 ((uint8_t)0x00) /*!< PAGE0寄存器 */
#define REG_PAGE1 ((uint8_t)0x20) /*!< PAGE1寄存器 */
#define REG_PAGE2 ((uint8_t)0x40) /*!< PAGE2寄存器 */
#define REG_PAGE3 ((uint8_t)0x60) /*!< PAGE3寄存器 */
#define REG_KEY ((uint8_t)0x80) /*!< KEY寄存器 */
#define REG_USID ((uint8_t)0x90) /*!< 用户ID寄存器 */
#define REG_WDGCNT ((uint8_t)0xA0) /*!< 24位看门狗计数器 */
#define REG_WDGRSTCTRL ((uint8_t)0xA3) /*!< 看门狗复位与控制寄存器 */
#define REG_RSTCNT ((uint8_t)0xA4) /*!< 看门狗复位信号宽度寄存器 */
#define REG_PAGE0PRO ((uint8_t)0xA8) /*!< PAGE0保护寄存器 */
#define REG_PAGE1PRO ((uint8_t)0xA9) /*!< PAGE1保护寄存器 */
#define REG_PAGE2PRO ((uint8_t)0xAA) /*!< PAGE2保护寄存器 */
#define REG_PAGE3PRO ((uint8_t)0xAB) /*!< PAGE3保护寄存器 */
#define REG_KEYPRO ((uint8_t)0xAC) /*!< KEY保护寄存器 */
#define REG_UIDPRO ((uint8_t)0xAD) /*!< USID保护寄存器 */
#define REG_PRT_CTRL ((uint8_t)0xAE) /*!< (0xA0~0xA6)保护寄存器 */
#define REG_DISABLE_INIT_PAGE ((uint8_t)0xAF) /*!< InitPage失效寄存器(只读) */
#define REG_MCMD ((uint8_t)0xB0) /*!< 命令寄存器 */
#define REG_TAr ((uint8_t)0xB1) /*!< 源PAGE寄存器 */
#define REG_TAd ((uint8_t)0xB2) /*!< 目的PAGE寄存器 */
#define REG_ES ((uint8_t)0xB3) /*!< 错误状态寄存器 */
#define REG_SYSCTRL ((uint8_t)0xB4) /*!< 系统控制寄存器 */
#define REG_VERSION0 ((uint8_t)0xB8) /*!< 芯片版本号寄存器 */
#define REG_MEMBUF ((uint8_t)0xC0) /*!< 数据交换区寄存器 */
#define REG_MACBUF ((uint8_t)0xE0) /*!< MAC输入寄存器 */
/*** @brief 寄存器位定义 ###############################################################
*/
/** @brief 看门狗复位与控制寄存器REG_WDGRSTCTRL(0xA3)位定义
*
*######################################################################################
* @比特位 @位定义 @复位值 @含义
*--------------------------------------------------------------------------------------
* 0 WDOG_EN 0 0:看门狗停止 1:看门狗启动
* 1 RFU 0 x: 未定义
* 2 SHA_RD_BYPASS 0 0:读PAGE时加密输出 1:读PAGE时直接输出
* 3 RFU 0 x: 未定义
* 4 RST_EN_N 0 0:复位输出使能 1:复位输出失能
* 5 RST_POLARITY 0 0:复位低有效 1:复位高有效
* 6 RFU 0 x: 未定义
* 7 RFU 0 x: 未定义
*######################################################################################
*/
#define WDOG_EN ((uint8_t)(1u << 0)) /*!< 看门狗使能控制位 */
#define SHA_RD_BYPASS ((uint8_t)(1u << 2)) /*!< 读PAGE时输出方式控制位 */
#define RST_EN_N ((uint8_t)(1u << 4)) /*!< 看门狗复位信号输出控制位 */
#define RST_POLARITY ((uint8_t)(1u << 5)) /*!< 看门狗复位信号极性控制位 */
/** @brief 执行状态寄存器REG_ES(0xB3)位定义
*
*######################################################################################
* @比特位 @位定义 @复位值 @含义
*--------------------------------------------------------------------------------------
* 0 ES_DONE 0 0:命令正执行中 1:命令执行完成
* 1 RFU 0 x: 未定义
* 2 RFU 0 x: 未定义
* 3 RFU 0 x: 未定义
* 4 ES_ERR 0 0:正常 1:错误
* 5 RFU 0 x: 未定义
* 6 RFU 0 x: 未定义
* 7 RFU 0 x: 未定义
*######################################################################################
*/
#define ES_DONE ((uint8_t)(1u << 0)) /*!< 命令执行完成状态位 */
#define ES_ERR ((uint8_t)(1u << 4)) /*!< 命令执行错误状态位 */
/** @brief 系统控制寄存器REG_SYSCTRL(0xB4)位定义
*
*######################################################################################
* @比特位 @位定义 @复位值 @含义
*--------------------------------------------------------------------------------------
* 0 LowPower_Bypass 0 0:正常工作状态 1:进入低功耗
* 1 RFU 0 x: 未定义
* 2 RFU 0 x: 未定义
* 3 RFU 0 x: 未定义
* 4 Wdog_En_Reg 0 0:看门狗失能 1:看门狗使能
* 5 RFU 0 x: 未定义
* 6 RFU 0 x: 未定义
* 7 RFU 0 x: 未定义
*######################################################################################
*/
#define LOWPOWER_EN ((uint8_t)(1u << 0)) /*!< 低功耗使能位 */
#define WDOG_EN_REG ((uint8_t)(1u << 4)) /*!< 看门狗使能位 */
/**
*@brief 函数声明
*/
void RJGT102_I2cDriverRegister(I2C_Driver_t *pI2cDriver);
ExecutionStatus_t RJGT102_Init(void);
ExecutionStatus_t RJGT102_InitUsid(const uint8_t *pUsidBuf);
ExecutionStatus_t RJGT102_InitPage(uint8_t PageAddr, const uint8_t *pPageBuf);
ExecutionStatus_t RJGT102_InitKey(const uint8_t *pKeyBuf);
ExecutionStatus_t RJGT102_AuthenticationDevice(uint8_t PageAddr, const uint8_t *pRngBuf, uint8_t *pMacBuf);
ExecutionStatus_t RJGT102_UpdateKey(uint8_t PageAddr, const uint8_t *pRngBuf);
ExecutionStatus_t RJGT102_WriteCtrlReg(uint8_t Addr, uint8_t ByteData);
ExecutionStatus_t RJGT102_ReadCtrlReg(uint8_t Addr, uint8_t *pByteData);
ExecutionStatus_t RJGT102_WritePage(uint8_t SrcPageAddr, uint8_t DstPageAddr, const uint8_t *pPageBuf, const uint8_t *pMacBuf);
ExecutionStatus_t RJGT102_ReadPage(uint8_t SrcPageAddr, uint8_t DstPageAddr, const uint8_t *pRngBuf, const uint8_t *pMacBuf, uint8_t *pPageBuf, uint8_t LenOfPage);
ExecutionStatus_t RJGT102_WdogInit(uint32_t Period, uint32_t RstSignalWidth, WDG_RstPolarity_t RstPolarity);
ExecutionStatus_t RJGT102_WdogCmd(WDG_CtrlState_t NewState);
ExecutionStatus_t RJGT102_WdogFeed(void);
ExecutionStatus_t RJGT102_SetProtection(uint8_t Addr);
ExecutionStatus_t RJGT102_ReadUsid(uint8_t *pUsidBuf);
ExecutionStatus_t RJGT102_ConfigReadPageMode(PageOutputMode_t mode);
ExecutionStatus_t RJGT102_GetExecutionStatus(void);
void RJGT102_GenerateRandom(uint8_t *pRngBuf);
void RJGT102_GetVersion(uint8_t *pVersionBuf);
uint8_t RJGT102_CheckVersion(void);
#ifdef __cplusplus
}
#endif
#endif /* end of __RJGT102_H__ */
三) rjgt102.c
/**
**************************************************************************************
* Copyright(c) 2015 Wuhan Runjet, All rights reserved.
**************************************************************************************
* @file rjgt102.c
* @author Wuhan Runjet software and test team
* @date 04-Feb-2015
* @version V1.00
* @brief Header file for RJGT102 chip.
**************************************************************************************
*
*/
#include <string.h>
#include "rjgt102.h"
/**@brief I2C驱动封装宏定义
*/
#define RJGT102_I2cOpen S_Rjgt102I2c->Open
#define RJGT102_I2cClose S_Rjgt102I2c->Close
#define RJGT102_I2cReadByte S_Rjgt102I2c->ReadByte
#define RJGT102_I2cWriteByte S_Rjgt102I2c->WriteByte
#define RJGT102_I2cRead S_Rjgt102I2c->Read
#define RJGT102_I2cWrite S_Rjgt102I2c->Write
/**
* @brief 静态全局变量定义
*/
static volatile uint32_t S_dwSeed = 0x0230A29F;
static volatile I2C_Driver_t *S_Rjgt102I2c = {0x00};
/**
***************************************************************************
* @brief 产生一个32位的整型随机数
* @param 无
* @retval 返回一个32位的整型随机数
***************************************************************************
*/
static uint32_t Rand(void)
{
S_dwSeed = S_dwSeed * 1103515245L + 12345;
return (uint32_t)(S_dwSeed / 65536L) % 32768L;
}
/**
***************************************************************************
* @brief 产生8个字节的随机数
* @param [OUT] pRngBuf 指向存储8字节随机数的数据区
* @retval 无
***************************************************************************
*/
void RJGT102_GenerateRandom(uint8_t *pRngBuf)
{
uint32_t RngBuf[2];
uint8_t i;
RngBuf[0] = Rand();
RngBuf[1] = Rand();
for (i = 0; i < 4; i++)
{
pRngBuf[i] = (uint8_t)((RngBuf[0] >> (8 * i)) & 0xFF);
pRngBuf[i + 4] = (uint8_t)((RngBuf[1] >> (8 * i)) & 0xFF);
}
}
/**
***************************************************************************
* @brief 获取执行状态
* @param 无
* @retval 返回状态值 @ref ExecutionStatus_t
* @arg 0x00 -命令正执行中
* @arg 0x01 -命令正确执行完成
* @arg 0x11 -命令错误执行完成
* @arg 0x10 -命令执行非法
* @arg 0xFF -命令执行超时
***************************************************************************
*/
ExecutionStatus_t RJGT102_GetExecutionStatus(void)
{
uint8_t ExecutionStatus = 0x00;
uint32_t TimeOut = CMD_EXECUTION_TIMEOUT;
do
{
RJGT102_I2cReadByte(&ExecutionStatus, REG_ES);
ExecutionStatus &= 0x11;
} while((!ExecutionStatus) && (--TimeOut));
if (0x00 == TimeOut)
{
ExecutionStatus = 0xFF;
}
return ((ExecutionStatus_t)ExecutionStatus);
}
/**
***************************************************************************
* @brief 版保芯片I2C驱动注册
* @param [IN] pI2cDriver 指向I2C驱动 @ref I2C_Driver_t
* @retval 返回状态值 @ref ExecutionStatus_t
***************************************************************************
*/
void RJGT102_I2cDriverRegister(I2C_Driver_t *pI2cDriver)
{
S_Rjgt102I2c = pI2cDriver;
}
/**
***************************************************************************
* @brief 版保芯片初始化
* @param 无
* @retval 返回状态值 @ref ExecutionStatus_t
***************************************************************************
*/
ExecutionStatus_t RJGT102_Init(void)
{
ExecutionStatus_t ExecutionStatus = ES_ERROR;
RJGT102_I2cOpen();
/*!< 上电后,检查我司版保芯片 */
if (RJGT102_CheckVersion())
{
/*!< 指定读PAGE区数据时,加密输出 */
ExecutionStatus = RJGT102_ConfigReadPageMode(PAGE_ENCRYPT_OUTPUT);
}
return ExecutionStatus;
}
/**
***************************************************************************
* @brief 初始化USID用户ID区
* @param [IN] pUsidBuf 指向8字节初始化用户ID区数据
* @retval 返回状态值 @ref ExecutionStatus_t
***************************************************************************
*/
ExecutionStatus_t RJGT102_InitUsid(const uint8_t *pUsidBuf)
{
uint8_t UsidBuf[8];
memcpy(UsidBuf, pUsidBuf, 8);
RJGT102_I2cWriteByte(CMD_CLEARCMD, REG_MCMD);
RJGT102_I2cWrite(REG_MEMBUF, UsidBuf, 8);
RJGT102_I2cWriteByte(CMD_INITUSID, REG_MCMD);
return (RJGT102_GetExecutionStatus());
}
/**
***************************************************************************
* @brief 初始化指定PAGEx(x=0-3)区
* @param [IN] PageAddr 指定待初始化PAGEx(x=0-3)的地址
* [IN] pPageBuf 指向32字节初始化PAGE区数据
* @retval 返回状态值 @ref ExecutionStatus_t
***************************************************************************
*/
ExecutionStatus_t RJGT102_InitPage(uint8_t PageAddr, const uint8_t *pPageBuf)
{
uint8_t PageBuf[32];
memcpy(PageBuf, pPageBuf, 32);
RJGT102_I2cWriteByte(CMD_CLEARCMD, REG_MCMD);
RJGT102_I2cWrite(REG_MEMBUF, PageBuf, 32);
RJGT102_I2cWriteByte(PageAddr, REG_TAd);
RJGT102_I2cWriteByte(CMD_INITPAGE, REG_MCMD);
return (RJGT102_GetExecutionStatus());
}
/**
***************************************************************************
* @brief 初始化KEY密钥区
* @param [IN] pKeyBuf 指向8字节初始化KEY区数据
* @retval 返回状态值 @ref ExecutionStatus_t
***************************************************************************
*/
ExecutionStatus_t RJGT102_InitKey(const uint8_t *pKeyBuf)
{
uint8_t KeyBuf[8];
memcpy(KeyBuf, pKeyBuf, 8);
RJGT102_I2cWriteByte(CMD_CLEARCMD, REG_MCMD);
RJGT102_I2cWrite(REG_MEMBUF, KeyBuf, 8);
RJGT102_I2cWriteByte(CMD_INITKEY, REG_MCMD);
return (RJGT102_GetExecutionStatus());
}
/**
***************************************************************************
* @brief 主机认证芯片以从芯片获取32字节MAC值
* @param [IN] PageAddr 指定参与MAC计算的PAGEx(x=0-3)的地址
* [IN] pRngBuf 指向参与MAC计算的8字节随机数
* [OUT] pMacBuf 指向用来存储32字节消息认证码MAC的数据区
* @retval 返回状态值 @ref ExecutionStatus_t
***************************************************************************
*/
ExecutionStatus_t RJGT102_AuthenticationDevice(uint8_t PageAddr, const uint8_t *pRngBuf, uint8_t *pMacBuf)
{
ExecutionStatus_t ExecutionStatus;
uint8_t RngBuf[8];
memcpy(RngBuf, pRngBuf, 8);
RJGT102_I2cWriteByte(CMD_CLEARCMD, REG_MCMD);
RJGT102_I2cWrite(REG_MEMBUF, RngBuf, 8);
RJGT102_I2cWriteByte(PageAddr, REG_TAr);
RJGT102_I2cWriteByte(CMD_AUTHENTICATION, REG_MCMD);
ExecutionStatus = RJGT102_GetExecutionStatus();
if (ES_NORMAL == ExecutionStatus)
{
RJGT102_I2cRead(REG_MEMBUF, pMacBuf, 32);
}
return ExecutionStatus;
}
/**
***************************************************************************
* @brief 更新KEY密钥区
* @param [IN] PageAddr 指定参与MAC计算的PAGEx(x=0-3)的地址
* [IN] pRngBuf 指向参与MAC计算的8字节随机数存储区
* @retval 返回状态值 @ref ExecutionStatus_t
***************************************************************************
*/
ExecutionStatus_t RJGT102_UpdateKey(uint8_t PageAddr, const uint8_t *pRngBuf)
{
uint8_t RngBuf[8];
memcpy(RngBuf, pRngBuf, 8);
RJGT102_I2cWriteByte(CMD_CLEARCMD, REG_MCMD);
RJGT102_I2cWrite(REG_MEMBUF, RngBuf, 8);
RJGT102_I2cWriteByte(PageAddr, REG_TAr);
RJGT102_I2cWriteByte(CMD_GENERATEKEY, REG_MCMD);
return (RJGT102_GetExecutionStatus());
}
/**
***************************************************************************
* @brief 向指定的控制寄存器(地址范围:0xA0~0xAE)写入1字节数据
* @param [IN] Addr 指定待写入地址
* [IN] ByteData 指定待写入的字节数据
* @retval 返回状态值 @ref ExecutionStatus_t
***************************************************************************
*/
ExecutionStatus_t RJGT102_WriteCtrlReg(uint8_t Addr, uint8_t ByteData)
{
RJGT102_I2cWriteByte(CMD_CLEARCMD, REG_MCMD);
RJGT102_I2cWriteByte(ByteData, REG_MEMBUF);
RJGT102_I2cWriteByte(Addr, REG_TAd);
RJGT102_I2cWriteByte(CMD_WRITE, REG_MCMD);
return (RJGT102_GetExecutionStatus());
}
/**
***************************************************************************
* @brief 从指定的控制寄存器(地址范围:0xA0-0xAF)读出1字节数据
* @param [IN] Addr 指定待读出地址
* [OUT] pByteData 指向待读出字节数据存储区
* @retval 返回状态值 @ref ExecutionStatus_t
***************************************************************************
*/
ExecutionStatus_t RJGT102_ReadCtrlReg(uint8_t Addr, uint8_t *pByteData)
{
ExecutionStatus_t ExecutionStatus;
RJGT102_I2cWriteByte(CMD_CLEARCMD, REG_MCMD);
RJGT102_I2cWriteByte(Addr, REG_TAd);
RJGT102_I2cWriteByte(CMD_READ, REG_MCMD);
ExecutionStatus = RJGT102_GetExecutionStatus();
if (ES_NORMAL == ExecutionStatus)
{
RJGT102_I2cReadByte(pByteData, REG_MEMBUF);
}
return ExecutionStatus;
}
/**
***************************************************************************
* @brief 向指定的目的PAGEx(x=0-3)认证写入32字节数据
* @param [IN] SrcPageAddr 指定参与MAC计算的源PAGE地址
* [IN] DstPageAddr 指定待写入的目的PAGE地址
* [IN] pPageBuf 指向待写入的32字节PAGE数据(注意:数据低8字节作为
* 随机数数据,参与MAC计算,软、硬件计算MAC时必须同
* 步将它作为当次随机数)
* [IN] pMacBuf 指向待写入的32字节MAC数据(此MAC由软件计算所得,
* 写入芯片内部作比较认证,相等方可将数据写入目的
* PAGE区,否则报错)
* @retval 返回状态值 @ref ExecutionStatus_t
***************************************************************************
*/
ExecutionStatus_t RJGT102_WritePage(uint8_t SrcPageAddr, uint8_t DstPageAddr, const uint8_t *pPageBuf, const uint8_t *pMacBuf)
{
uint8_t DataBuf[32];
RJGT102_I2cWriteByte(CMD_CLEARCMD, REG_MCMD);
memcpy(DataBuf, pPageBuf, 32);
RJGT102_I2cWrite(REG_MEMBUF, DataBuf, 32);
memcpy(DataBuf, pMacBuf, 32);
RJGT102_I2cWrite(REG_MACBUF, DataBuf, 32);
RJGT102_I2cWriteByte(SrcPageAddr, REG_TAr);
RJGT102_I2cWriteByte(DstPageAddr, REG_TAd);
RJGT102_I2cWriteByte(CMD_WRITE, REG_MCMD);
return (RJGT102_GetExecutionStatus());
}
/**
***************************************************************************
* @brief 从指定的目的PAGEx(x=0-3)认证读出数据
* @param [IN] SrcPageAddr 指定参与MAC计算的源PAGE地址
* [IN] DstPageAddr 指定待读出的目的PAGE地址
* [IN] pRngBuf 指向参与MAC计算的8字节随机数存储区
* [IN] pMacBuf 指向待写入的32字节MAC数据(此MAC由软件计算所得,
* 写入芯片内部作比较认证,相等时才允许从PAGE区读
* 出数据,否则报错
* [OUT] pPageBuf 指向读出的PAGE数据存储区
* [IN] LenOfPage 指定待读出的数据长度
* @retval 返回状态值 @ref ExecutionStatus_t
***************************************************************************
*/
ExecutionStatus_t RJGT102_ReadPage(uint8_t SrcPageAddr,
uint8_t DstPageAddr,
const uint8_t *pRngBuf,
const uint8_t *pMacBuf,
uint8_t *pPageBuf,
uint8_t LenOfPage)
{
ExecutionStatus_t ExecutionStatus;
uint8_t i;
uint8_t TmpReg;
uint8_t DataBuf[32];
RJGT102_I2cWriteByte(CMD_CLEARCMD, REG_MCMD);
memcpy(DataBuf, pRngBuf, 8);
RJGT102_I2cWrite(REG_MEMBUF, DataBuf, 8);
memcpy(DataBuf, pMacBuf, 32);
RJGT102_I2cWrite(REG_MACBUF, DataBuf, 32);
RJGT102_I2cWriteByte(SrcPageAddr, REG_TAr);
RJGT102_I2cWriteByte(DstPageAddr, REG_TAd);
RJGT102_I2cWriteByte(CMD_READ, REG_MCMD);
ExecutionStatus = RJGT102_GetExecutionStatus();
if (ES_NORMAL == ExecutionStatus)
{
RJGT102_I2cRead(REG_MEMBUF, pPageBuf, LenOfPage);
ExecutionStatus = RJGT102_ReadCtrlReg(REG_WDGRSTCTRL, &TmpReg);
if (ES_NORMAL == ExecutionStatus)
{
if (0x00 == (TmpReg & SHA_RD_BYPASS))
{
for (i = 0; i < LenOfPage; i++)
{
pPageBuf[i] ^= pMacBuf[i];
}
}
}
}
return ExecutionStatus;
}
/**
***************************************************************************
* @brief 看门狗初始化
* @param [IN] Period 复位周期(范围:0x000000-0xFFFFFF)
* [IN] RstSignalWidth 复位有效信号宽度(范围:0x000000-0xFFFFFF)
* [IN] RstPolarity 复位信号极性 @ref WDG_RstPolarity_t
* @arg LOW_VALID 复位信号低有效
* @arg HIGH_VALID 复位信号高有效
* @retval 返回状态值 @ref ExecutionStatus_t
***************************************************************************
*/
ExecutionStatus_t RJGT102_WdogInit(uint32_t Period, uint32_t RstSignalWidth, WDG_RstPolarity_t RstPolarity)
{
ExecutionStatus_t ExecutionStatus;
uint8_t RegAddr;
uint8_t TmpReg;
uint8_t i;
for (i = 0; i < 3; i++)
{
TmpReg = (uint8_t)((Period >> 8*i) & 0xFF);
RegAddr = REG_WDGCNT + i;
ExecutionStatus = RJGT102_WriteCtrlReg(RegAddr, TmpReg);
if (ES_NORMAL != ExecutionStatus)
{
goto RetExeStatus;
}
TmpReg = (uint8_t)((RstSignalWidth >> 8*i) & 0xFF);
RegAddr = REG_RSTCNT + i;
ExecutionStatus = RJGT102_WriteCtrlReg(RegAddr, TmpReg);
if (ES_NORMAL != ExecutionStatus)
{
goto RetExeStatus;
}
}
ExecutionStatus = RJGT102_ReadCtrlReg(REG_WDGRSTCTRL, &TmpReg);
if (ES_NORMAL == ExecutionStatus)
{
TmpReg &= ~(RST_POLARITY | RST_EN_N);
if (HIGH_VALID == RstPolarity)
{
TmpReg |= RST_POLARITY;
}
ExecutionStatus = RJGT102_WriteCtrlReg(REG_WDGRSTCTRL, TmpReg);
}
RetExeStatus:
return ExecutionStatus;
}
/**
***************************************************************************
* @brief 看门狗控制
* @param [IN] NewState 看门狗控制状态
* @arg WDG_ENABLE 看门狗启动
* @arg WDG_DISABLE 看门狗停止
* @retval 返回状态值 @ref ExecutionStatus_t
***************************************************************************
*/
ExecutionStatus_t RJGT102_WdogCmd(WDG_CtrlState_t NewState)
{
ExecutionStatus_t ExecutionStatus;
uint8_t TmpReg;
uint8_t TmpReg1;
RJGT102_I2cRead(REG_SYSCTRL, &TmpReg1, 1);
ExecutionStatus = RJGT102_ReadCtrlReg(REG_WDGRSTCTRL, &TmpReg);
if (ES_NORMAL == ExecutionStatus)
{
TmpReg1 &= ~WDOG_EN_REG;
TmpReg &= ~WDOG_EN;
if (WDG_DISABLE != NewState)
{
TmpReg |= WDOG_EN;
TmpReg1 |= WDOG_EN_REG;
}
ExecutionStatus = RJGT102_WriteCtrlReg(REG_WDGRSTCTRL, TmpReg);
if (ES_NORMAL == ExecutionStatus)
{
RJGT102_I2cWriteByte(TmpReg1, REG_SYSCTRL);
}
}
return ExecutionStatus;
}
/**
***************************************************************************
* @brief 看门狗喂狗
* @param 无
* @retval 返回状态值 @ref ExecutionStatus_t
***************************************************************************
*/
ExecutionStatus_t RJGT102_WdogFeed(void)
{
return (RJGT102_WdogCmd(WDG_ENABLE));
}
/**
***************************************************************************
* @brief 读取芯片REG_USID用户ID
* @param [OUT] pUsidBuf 指向存放8字节用户ID的数据缓冲区
* @retval 返回状态值 @ref ExecutionStatus_t
***************************************************************************
*/
ExecutionStatus_t RJGT102_ReadUsid(uint8_t *pUsidBuf)
{
ExecutionStatus_t ExecutionStatus;
RJGT102_I2cWriteByte(CMD_CLEARCMD, REG_MCMD);
RJGT102_I2cWriteByte(REG_USID, REG_TAd);
RJGT102_I2cWriteByte(CMD_READ, REG_MCMD);
ExecutionStatus = RJGT102_GetExecutionStatus();
if (ES_NORMAL == ExecutionStatus)
{
RJGT102_I2cRead(REG_MEMBUF, pUsidBuf, 8);
}
return ExecutionStatus;
}
/**
***************************************************************************
* @brief 将指定区域设置保护
* @param [IN] Addr 指明待保护区域的地址
* @arg PAGExPRO(x=0-3) PAGEx区设保护
* @arg KEYPRO KEY区设保护
* @arg UIDPRO REG_USID区设保护
* @arg PRT_CTRL 控制寄存器区(0xA0~0xA6)设保护
* @retval 返回状态值 @ref ExecutionStatus_t
***************************************************************************
*/
ExecutionStatus_t RJGT102_SetProtection(uint8_t Addr)
{
RJGT102_WriteCtrlReg(Addr, REGIONAL_PROTECTION_CODE);
return (RJGT102_GetExecutionStatus());
}
/**
***************************************************************************
* @brief 获取芯片版本号
* @param [IN] pVersionBuf 指向存储4字节版本号的缓冲区
* @retval 无
***************************************************************************
*/
void RJGT102_GetVersion(uint8_t *pVersionBuf)
{
RJGT102_I2cRead(REG_VERSION0, pVersionBuf, 4);
}
/**
***************************************************************************
* @brief 检测是否是我司版保芯片
* @param 无
* @retval 返回状态值
* @arg 0x00 表示不是或没有找到我司芯片
* @arg 0x01 表示是我司芯片
***************************************************************************
*/
uint8_t RJGT102_CheckVersion(void)
{
const uint8_t Version[4] = {0x32, 0x30, 0x84, 0x71};
uint8_t VersionBuf[4];
RJGT102_I2cRead(REG_VERSION0, VersionBuf, 4);
return (!memcmp(VersionBuf, Version, 4));
}
/**
***************************************************************************
* @brief 读PAGE时,输出模式配置
* @param [IN] mode @ref PageOutputMode_t
* @arg PAGE_ENCRYPT_OUTPUT 读PAGE时,加密输出
* @arg PAGE_DIRECT_OUTPUT 读PAGE时,直接输出
* @retval 返回状态值 @ref ExecutionStatus_t
***************************************************************************
*/
ExecutionStatus_t RJGT102_ConfigReadPageMode(PageOutputMode_t mode)
{
ExecutionStatus_t ExecutionStatus;
uint8_t TmpReg;
ExecutionStatus = RJGT102_ReadCtrlReg(REG_WDGRSTCTRL, &TmpReg);
if (ES_NORMAL == ExecutionStatus)
{
if (PAGE_ENCRYPT_OUTPUT != mode)
{
TmpReg |= SHA_RD_BYPASS;
}
else
{
TmpReg &= ~SHA_RD_BYPASS;
}
ExecutionStatus = RJGT102_WriteCtrlReg(REG_WDGRSTCTRL, TmpReg);
}
return ExecutionStatus;
}