//=========================== 加密芯片 SMEC98SP 接口 ===========================// #include "smec98sp.h" #ifdef SMEC_CHIP #include #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 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