|
@@ -0,0 +1,2919 @@
|
|
|
|
+/****************************************************************************
|
|
|
|
+ *
|
|
|
|
+ * Copy right: Qx.
|
|
|
|
+ * File name: UartTask.c
|
|
|
|
+ * Description: 串口任务
|
|
|
|
+ * History: 2021-03-05
|
|
|
|
+ *
|
|
|
|
+ * 2021-04-11:可以通过Ota线路升级Bms保护板
|
|
|
|
+ ****************************************************************************/
|
|
|
|
+#include "bsp.h"
|
|
|
|
+#include "bsp_custom.h"
|
|
|
|
+#include "osasys.h"
|
|
|
|
+#include "ostask.h"
|
|
|
|
+#include "queue.h"
|
|
|
|
+#include "ps_event_callback.h"
|
|
|
|
+#include "cmisim.h"
|
|
|
|
+#include "cmimm.h"
|
|
|
|
+#include "cmips.h"
|
|
|
|
+#include "sockets.h"
|
|
|
|
+#include "psifevent.h"
|
|
|
|
+#include "ps_lib_api.h"
|
|
|
|
+#include "lwip/netdb.h"
|
|
|
|
+//#include <cis_def.h>
|
|
|
|
+#include "debug_log.h"
|
|
|
|
+#include "slpman_ec616.h"
|
|
|
|
+#include "plat_config.h"
|
|
|
|
+#include "ec_tcpip_api.h"
|
|
|
|
+#include "hal_module_adapter.h"
|
|
|
|
+#include "UartTask.h"
|
|
|
|
+#include "MainTask.h"
|
|
|
|
+#include <stdlib.h>
|
|
|
|
+#include "app.h"
|
|
|
|
+#include "numeric.h"
|
|
|
|
+#include "Fota.h"
|
|
|
|
+#include "signal.h"
|
|
|
|
+//全局变量输入区
|
|
|
|
+extern UINT32 Timer_count;
|
|
|
|
+extern volatile BOOL Sleep_flag;
|
|
|
|
+extern AppNVMDataType AppNVMData;
|
|
|
|
+extern AppDataBody AppDataInfo;
|
|
|
|
+extern UINT8 WorkFlag;
|
|
|
|
+//全局变量输出区
|
|
|
|
+BOOL UartBattInfoRecvFlag = false;
|
|
|
|
+QueueHandle_t UartWriteCmdHandle = NULL;
|
|
|
|
+UINT8 BattChrgEndFlag;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+//
|
|
|
|
+
|
|
|
|
+extern ARM_DRIVER_USART Driver_USART1;
|
|
|
|
+static ARM_DRIVER_USART *USARTdrv = &Driver_USART1;
|
|
|
|
+volatile bool isRecvTimeout = false;
|
|
|
|
+volatile bool isRecvComplete = false;
|
|
|
|
+
|
|
|
|
+//线程声明区
|
|
|
|
+static StaticTask_t gProcess_Uart_Task_t;
|
|
|
|
+static UINT8 gProcess_Uart_TaskStack[PROC_UART_TASK_STACK_SIZE];
|
|
|
|
+static osThreadId_t UartTaskId = NULL;
|
|
|
|
+static process_Uart gProcess_Uart_Task = PROCESS_UART_STATE_IDLE;
|
|
|
|
+#define PROC_UART_STATE_SWITCH(a) (gProcess_Uart_Task = a)
|
|
|
|
+
|
|
|
|
+//函数声明区
|
|
|
|
+void USART_callback(uint32_t event);
|
|
|
|
+UINT8 Uart_DataRecv_func(Uart_Read_Msg_Type Uart_Read_Msg_Fun,UINT8* Uart_Recv_Buffer_Fun);
|
|
|
|
+static BOOL uartBattInfoDecode(UINT8* dataPtr);
|
|
|
|
+UINT8 Uart_WriteCmd_func(Uart_Write_Data_Type UartWriteData);
|
|
|
|
+UINT16 crc_chk(UINT8* data, UINT8 length);
|
|
|
|
+void battSOCDisplay(void);
|
|
|
|
+void battErrorStateDisplay(void);
|
|
|
|
+void battWarningStateDisplay(void);
|
|
|
|
+void battLockStateDisplay(UINT8 lockState);
|
|
|
|
+void relayPWMControl(void);
|
|
|
|
+void SP_BMS_Update_Service(void);
|
|
|
|
+BOOL BattHeaterSwitch(UINT8* heaterSwitch);
|
|
|
|
+UINT16 encryptionAlgorithm (UINT16 plainText);
|
|
|
|
+UINT8 decryptionAlgorithm (UINT16 cipherText);
|
|
|
|
+UINT8 Uart_Encrypt_Send(void);
|
|
|
|
+UINT8 BmsErrorDecode(UINT32 battWarningState);
|
|
|
|
+//BMS升级函数声明
|
|
|
|
+UINT8 SP_BMS_Update_CheckSUM(UINT8* pSendData,UINT8 len);
|
|
|
|
+void SP_BMS_Update_Service();
|
|
|
|
+UINT8 SP_BMS_Update_Query(UINT8* pSend,UINT32 sendLen, UINT8* pRead, UINT32 readLen, UINT32 timeout);
|
|
|
|
+
|
|
|
|
+updateBMSStatus MS_BMS_Update_Service();
|
|
|
|
+UINT16 MS_BMS_Update_CRC16(UINT8* pSendData,UINT16 len);
|
|
|
|
+UINT8 MS_BMS_Update_Query(UINT8* pSend,UINT32 sendLen, UINT8* pRead, UINT32 readLen, UINT32 timeout);
|
|
|
|
+//Uart线程任务区
|
|
|
|
+static void UartTask(void* arg)
|
|
|
|
+{
|
|
|
|
+ USARTdrv->Initialize(USART_callback);
|
|
|
|
+ USARTdrv->PowerControl(ARM_POWER_FULL);
|
|
|
|
+ USARTdrv->Control(ARM_USART_MODE_ASYNCHRONOUS |
|
|
|
|
+ ARM_USART_DATA_BITS_8 |
|
|
|
|
+ ARM_USART_PARITY_NONE |
|
|
|
|
+ ARM_USART_STOP_BITS_1 |
|
|
|
|
+ ARM_USART_FLOW_CONTROL_NONE, 9600);
|
|
|
|
+ PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_ENCRYPT);
|
|
|
|
+ UINT16 Reg_Num = 0;
|
|
|
|
+ UINT16 Uart_Uds_LEN;
|
|
|
|
+ UINT16 Uart_Recv_LEN;
|
|
|
|
+ UINT32 currentTimerCount=0;
|
|
|
|
+ BOOL uartReadSuccessFlag = false;
|
|
|
|
+ Uart_Read_Msg_Type Uart_Read_Msg;
|
|
|
|
+ memset(&(Uart_Read_Msg),0x00,sizeof(Uart_Read_Msg_Type));
|
|
|
|
+ Uart_Write_Data_Type UartWriteData; //Uart控制命令
|
|
|
|
+ memset(&(UartWriteData),0x00,sizeof(Uart_Write_Data_Type));
|
|
|
|
+ UartReadMsgType UartReadMsg;
|
|
|
|
+ memset(&(UartReadMsg.UartFlag),0x00,sizeof(UartReadMsgType));
|
|
|
|
+ if(UartWriteCmdHandle == NULL)//Uart控制命令传输指针
|
|
|
|
+ {
|
|
|
|
+ UartWriteCmdHandle = osMessageQueueNew(3,sizeof(Uart_Write_Data_Type), NULL);
|
|
|
|
+ }
|
|
|
|
+ //上电起始控制区域
|
|
|
|
+ while (1)
|
|
|
|
+ {
|
|
|
|
+ switch (gProcess_Uart_Task)
|
|
|
|
+ {
|
|
|
|
+ case PROCESS_UART_STATE_ENCRYPT:
|
|
|
|
+ {
|
|
|
|
+ UINT8 EncryptFlag=0x00;
|
|
|
|
+ UINT8 EncryptCount=0;
|
|
|
|
+ while(EncryptFlag!=0x01&&EncryptCount<=3)
|
|
|
|
+ {
|
|
|
|
+ EncryptFlag = Uart_Encrypt_Send();
|
|
|
|
+ EncryptCount++;
|
|
|
|
+ }
|
|
|
|
+ PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_IDLE);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case PROCESS_UART_STATE_IDLE:
|
|
|
|
+ {
|
|
|
|
+ osDelay(100);
|
|
|
|
+ if(Sleep_flag)
|
|
|
|
+ {
|
|
|
|
+ PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_SLEEP);
|
|
|
|
+ }
|
|
|
|
+ else if(Timer_count%10==0)
|
|
|
|
+ {
|
|
|
|
+ #ifdef USING_PRINTF1
|
|
|
|
+ printf("[%d]Uart Timer 1s:%d,uartReadSuccessFlag:%d\n",__LINE__,Timer_count,uartReadSuccessFlag);
|
|
|
|
+ #endif
|
|
|
|
+ if(osMessageQueueGet(UartWriteCmdHandle,&UartWriteData,0,0)==osOK)
|
|
|
|
+ {
|
|
|
|
+ #ifdef USING_PRINTF1
|
|
|
|
+ printf("[%d]UartWriteCmdHandle :%x\n",__LINE__,UartWriteData.WriteCmd);
|
|
|
|
+ #endif
|
|
|
|
+ PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_WRITE);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_READ);
|
|
|
|
+ }
|
|
|
|
+ if(UartReadMsg.Header[2]>0)
|
|
|
|
+ {
|
|
|
|
+ uartReadSuccessFlag = true;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ uartReadSuccessFlag = false;
|
|
|
|
+ }
|
|
|
|
+ if(Timer_count-currentTimerCount >= 1)
|
|
|
|
+ {
|
|
|
|
+ if(AppNVMData.isBattLocked != 0)
|
|
|
|
+ {
|
|
|
|
+ battLockStateDisplay(TRUE);
|
|
|
|
+ }
|
|
|
|
+ else if(uartReadSuccessFlag)
|
|
|
|
+ {
|
|
|
|
+ battSOCDisplay();
|
|
|
|
+ battErrorStateDisplay();
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ battWarningStateDisplay();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ currentTimerCount = Timer_count;
|
|
|
|
+ if(BMS_Fota_update_flag)
|
|
|
|
+ {
|
|
|
|
+ if(WorkFlag==0x00)
|
|
|
|
+ {
|
|
|
|
+ PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_UPDATE);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ if(AppNVMData.isBattLocked==TRUE && ((UartReadMsg.data[(0x09+BATT_CELL_VOL_NUM+BATT_TEMP_NUM+2)*2+1])>>1)&0x03!=0x00 && Timer_count%10==0)//try to lock
|
|
|
|
+ {
|
|
|
|
+ UartWriteData.WriteCmd = 0x01;
|
|
|
|
+ UartWriteData.Data[0] = 0x00;
|
|
|
|
+ UartWriteData.Data[1] = 0x00;
|
|
|
|
+ osMessageQueuePut(UartWriteCmdHandle,&UartWriteData,0,1000);
|
|
|
|
+ PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_READ);
|
|
|
|
+ }
|
|
|
|
+ else if (AppNVMData.isBattLocked==FALSE && ((UartReadMsg.data[(0x09+BATT_CELL_VOL_NUM+BATT_TEMP_NUM+2)*2+1])>>1)&0x03==0x00 && Timer_count%10==0 ) // try to unlock
|
|
|
|
+ {
|
|
|
|
+ UartWriteData.WriteCmd = 0x01;
|
|
|
|
+ UartWriteData.Data[0] = 0x00;
|
|
|
|
+ UartWriteData.Data[1] = 0x03;
|
|
|
|
+ osMessageQueuePut(UartWriteCmdHandle,&UartWriteData,0,1000);
|
|
|
|
+ PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_READ);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case PROCESS_UART_STATE_READ:
|
|
|
|
+ {
|
|
|
|
+ UINT16 CRC_chk_buffer;
|
|
|
|
+ Reg_Num = 0x21+BATT_CELL_VOL_NUM+BATT_TEMP_NUM + 2;//按照协议里面的0x21+X+N的结束地址
|
|
|
|
+ Uart_Read_Msg.Bms_Address = BMS_ADDRESS_CODE;
|
|
|
|
+ Uart_Read_Msg.Bms_Funcode = UART_READ_CODE;
|
|
|
|
+ Uart_Read_Msg.Reg_Begin_H = 0x00;
|
|
|
|
+ Uart_Read_Msg.Reg_Begin_L= 0x00;
|
|
|
|
+ Uart_Read_Msg.Reg_Num_H = Reg_Num>>8;
|
|
|
|
+ Uart_Read_Msg.Reg_Num_L = Reg_Num;
|
|
|
|
+ Uart_Uds_LEN = Reg_Num*2;
|
|
|
|
+ memset(UartReadMsg.Header,0x00,Uart_Uds_LEN);
|
|
|
|
+ CRC_chk_buffer = crc_chk((UINT8 *)&Uart_Read_Msg,6);
|
|
|
|
+ Uart_Read_Msg.CRC_L = CRC_chk_buffer;
|
|
|
|
+ Uart_Read_Msg.CRC_H = CRC_chk_buffer>>8;
|
|
|
|
+ //Uart_Recv_LEN = Uart_DataRecv_func((UINT8 *)&Uart_Read_Msg,(UINT8*)UartReadMsg.Header);
|
|
|
|
+ Uart_Recv_LEN = Uart_DataRecv_func(Uart_Read_Msg,(UINT8*)(UartReadMsg.Header));
|
|
|
|
+ if(Uart_Recv_LEN>0)
|
|
|
|
+ {
|
|
|
|
+ UartBattInfoRecvFlag = TRUE;
|
|
|
|
+ uartBattInfoDecode(UartReadMsg.data);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ UartBattInfoRecvFlag = FALSE;
|
|
|
|
+ }
|
|
|
|
+ UartReadMsg.len = Uart_Recv_LEN;
|
|
|
|
+ PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_IDLE);
|
|
|
|
+ if( battWorkState ==0x02)
|
|
|
|
+ {
|
|
|
|
+ BattChrgEndFlag=TRUE;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ BattChrgEndFlag=FALSE;
|
|
|
|
+ }
|
|
|
|
+ #ifdef USING_PRINTF1
|
|
|
|
+ printf("\nUart_Recv_buffer: ");
|
|
|
|
+ for(int i=0;i<Uart_Recv_LEN;i++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",*((UINT8 *)&UartReadMsg.Header+i));
|
|
|
|
+ }
|
|
|
|
+ printf("\n");
|
|
|
|
+ #endif
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case PROCESS_UART_STATE_WRITE:
|
|
|
|
+ {
|
|
|
|
+ Uart_WriteCmd_func(UartWriteData);
|
|
|
|
+ PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_IDLE);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case PROCESS_UART_STATE_UPDATE:
|
|
|
|
+ UartBattInfoRecvFlag = FALSE;
|
|
|
|
+ #if BMS_MANUFACTURE==1
|
|
|
|
+ {
|
|
|
|
+ SP_BMS_Update_Service();
|
|
|
|
+ }
|
|
|
|
+ #elif BMS_MANUFACTURE==2
|
|
|
|
+ MS_BMS_Update_Service();
|
|
|
|
+ #endif
|
|
|
|
+
|
|
|
|
+ PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_IDLE);
|
|
|
|
+ BMS_Fota_update_flag = FALSE;
|
|
|
|
+ break;
|
|
|
|
+ case PROCESS_UART_STATE_SLEEP:
|
|
|
|
+ {
|
|
|
|
+ USARTdrv->PowerControl(ARM_POWER_LOW);
|
|
|
|
+ while(TRUE)
|
|
|
|
+ {
|
|
|
|
+ osDelay(60000/portTICK_PERIOD_MS);
|
|
|
|
+ }
|
|
|
|
+ osThreadExit();
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+//Uart 接收的数据解码
|
|
|
|
+static BOOL uartBattInfoDecode(UINT8* dataPtr)
|
|
|
|
+{
|
|
|
|
+ //BattInfoType battInfo;
|
|
|
|
+ UINT8 i,temp=0;
|
|
|
|
+ UINT8 TEMP_NUM = BATT_TEMP_NUM + BATT_OTHER_TEMP_NUM;
|
|
|
|
+ UINT16 Batt_current;
|
|
|
|
+ for(i=0;i<BATT_CELL_VOL_NUM;i++)
|
|
|
|
+ {
|
|
|
|
+ battCellU[i] = (dataPtr[(0x02+i)*2] << 8) | dataPtr[(0x02+i)*2 + 1];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ battWorkState = (dataPtr[(0x03+BATT_CELL_VOL_NUM)*2+1])&0x03;//电池状态(原始数据),0表示静置,1表示放电,2表示充电
|
|
|
|
+
|
|
|
|
+ for(i=0; i<BATT_TEMP_NUM; i++)
|
|
|
|
+ {
|
|
|
|
+ battCellTemp[i] = dataPtr[(0x06+BATT_CELL_VOL_NUM+i)*2+1];
|
|
|
|
+ }
|
|
|
|
+ MOSTemp = dataPtr[(0x06+BATT_CELL_VOL_NUM+BATT_TEMP_NUM)*2+1];
|
|
|
|
+ packTemp = dataPtr[(0x06+BATT_CELL_VOL_NUM+BATT_TEMP_NUM+1)*2+1];
|
|
|
|
+
|
|
|
|
+ Batt_current = (dataPtr[(0x02+BATT_CELL_VOL_NUM)*2]<<8)|(dataPtr[(0x02+BATT_CELL_VOL_NUM)*2+1]);
|
|
|
|
+ //原始数据:充电为负,放电为正
|
|
|
|
+ if(battWorkState == 0x02) //充电过程
|
|
|
|
+ {
|
|
|
|
+ if(Batt_current >0x8000)// 数据为负
|
|
|
|
+ {
|
|
|
|
+ //求补码,结果为负
|
|
|
|
+ Batt_current = (UINT16)((UINT16)(~(Batt_current))+1);
|
|
|
|
+ Batt_current = Batt_current/10;
|
|
|
|
+ AppDataInfo.BattCurrentNegFlag = -1;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ //源码,结果为负
|
|
|
|
+ Batt_current = Batt_current/10;
|
|
|
|
+ AppDataInfo.BattCurrentNegFlag = -1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else //放电过程
|
|
|
|
+ {
|
|
|
|
+ if(Batt_current >0x8000)// 数据为负
|
|
|
|
+ {
|
|
|
|
+ //求补码,结果为正
|
|
|
|
+ Batt_current = (UINT16)((UINT16)(~(Batt_current))+1);
|
|
|
|
+ Batt_current = Batt_current/10;
|
|
|
|
+ AppDataInfo.BattCurrentNegFlag = 1;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ //源码,结果为正
|
|
|
|
+ Batt_current = Batt_current/10;
|
|
|
|
+ AppDataInfo.BattCurrentNegFlag = 1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ battI = Batt_current*AppDataInfo.BattCurrentNegFlag + 0x2710;
|
|
|
|
+ //bit0 ~ bit31 represent cell0 ~ cell31
|
|
|
|
+ battBalanceoInfo = dataPtr[(0x06+BATT_CELL_VOL_NUM+TEMP_NUM)*2+1] | (dataPtr[(0x06+BATT_CELL_VOL_NUM+TEMP_NUM)*2] <<8) + (dataPtr[(0x07+BATT_CELL_VOL_NUM+TEMP_NUM)*2+1]<<16) | (dataPtr[(0x07+BATT_CELL_VOL_NUM+TEMP_NUM)*2] <<24);
|
|
|
|
+
|
|
|
|
+ bmsHwVersion = dataPtr[(0x08+BATT_CELL_VOL_NUM+TEMP_NUM)*2+1];
|
|
|
|
+ bmsSwVersion = dataPtr[(0x08+BATT_CELL_VOL_NUM+TEMP_NUM)*2];
|
|
|
|
+
|
|
|
|
+ temp = ((dataPtr[(0x09+BATT_CELL_VOL_NUM+TEMP_NUM)*2+1])>>1)&0x03;
|
|
|
|
+ battMOSSwitchState = ((temp&0x01)<<1)|((temp&0x02)>>1);
|
|
|
|
+ if(AppNVMData.isBattLocked==TRUE)
|
|
|
|
+ {
|
|
|
|
+ battMOSSwitchState = battMOSSwitchState |(0x01<<2);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ battMOSSwitchState = battMOSSwitchState |(0x00<<2);
|
|
|
|
+ }
|
|
|
|
+ battWarningState = (dataPtr[(0x09+BATT_CELL_VOL_NUM+TEMP_NUM)*2+0]<<16) | (dataPtr[(0x0A+BATT_CELL_VOL_NUM+TEMP_NUM)*2+0] << 8) |(dataPtr[(0x0A+BATT_CELL_VOL_NUM+TEMP_NUM)*2+1]);
|
|
|
|
+ battSOC = dataPtr[(0x0B+BATT_CELL_VOL_NUM+TEMP_NUM)*2+1];
|
|
|
|
+ battSOH = dataPtr[(0x0C+BATT_CELL_VOL_NUM+TEMP_NUM)*2+1];
|
|
|
|
+ Battdesigncap = (dataPtr[(0x0E+BATT_CELL_VOL_NUM+TEMP_NUM)*2])<<24|(dataPtr[(0x0E+BATT_CELL_VOL_NUM+TEMP_NUM)*2+1])<<16|(dataPtr[(0x0F+BATT_CELL_VOL_NUM+TEMP_NUM)*2])<<8|(dataPtr[(0x0F+BATT_CELL_VOL_NUM+TEMP_NUM)*2+1]);
|
|
|
|
+ battPackVol =((dataPtr[(0x18+BATT_CELL_VOL_NUM+TEMP_NUM)*2])<<8|(dataPtr[(0x18+BATT_CELL_VOL_NUM+TEMP_NUM)*2+1]))/10; //uint 100mV
|
|
|
|
+ maxCellVol = (dataPtr[(0x19+BATT_CELL_VOL_NUM+TEMP_NUM)*2] << 8) | dataPtr[(0x19+BATT_CELL_VOL_NUM+TEMP_NUM)*2 + 1];
|
|
|
|
+ minCellVol = (dataPtr[(0x1A+BATT_CELL_VOL_NUM+TEMP_NUM)*2] << 8) | dataPtr[(0x1A+BATT_CELL_VOL_NUM+TEMP_NUM)*2 + 1];
|
|
|
|
+ battHeatEnableState = dataPtr[(0x1C+BATT_CELL_VOL_NUM+TEMP_NUM)*2+1]&0x01;
|
|
|
|
+
|
|
|
|
+ maxCellTemp = 0x00;
|
|
|
|
+ minCellTemp = 0xFF;
|
|
|
|
+ for(i=0;i<BATT_TEMP_NUM;i++)
|
|
|
|
+ {
|
|
|
|
+ maxCellTemp = max(maxCellTemp,battCellTemp[i]);
|
|
|
|
+ minCellTemp = min(minCellTemp,battCellTemp[i]);
|
|
|
|
+ }
|
|
|
|
+ nbSwVersion = APPSWVERSION;
|
|
|
|
+ nbHwVersion = HWVERSION;
|
|
|
|
+ BmsErrorDecode(battWarningState);
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+//Uart线程初始化
|
|
|
|
+void UartTaskInit(void *arg)
|
|
|
|
+{
|
|
|
|
+ osThreadAttr_t task_attr;
|
|
|
|
+ memset(&task_attr,0,sizeof(task_attr));
|
|
|
|
+ memset(gProcess_Uart_TaskStack, 0xA5, PROC_UART_TASK_STACK_SIZE);
|
|
|
|
+ task_attr.name = "Uart_Task";
|
|
|
|
+ task_attr.stack_mem = gProcess_Uart_TaskStack;
|
|
|
|
+ task_attr.stack_size = PROC_UART_TASK_STACK_SIZE;
|
|
|
|
+ task_attr.priority = osPriorityBelowNormal7;
|
|
|
|
+ task_attr.cb_mem = &gProcess_Uart_Task_t;
|
|
|
|
+ task_attr.cb_size = sizeof(StaticTask_t);
|
|
|
|
+ UartTaskId = osThreadNew(UartTask, NULL, &task_attr);
|
|
|
|
+}
|
|
|
|
+void UartTaskDeInit(void *arg)
|
|
|
|
+{
|
|
|
|
+ osThreadTerminate(UartTaskId);
|
|
|
|
+ UartTaskId = NULL;
|
|
|
|
+}
|
|
|
|
+//函数区
|
|
|
|
+//Uart回调程序
|
|
|
|
+void USART_callback(uint32_t event)
|
|
|
|
+{
|
|
|
|
+ if(event & ARM_USART_EVENT_RX_TIMEOUT)
|
|
|
|
+ {
|
|
|
|
+ isRecvTimeout = true;
|
|
|
|
+ }
|
|
|
|
+ if(event & ARM_USART_EVENT_RECEIVE_COMPLETE)
|
|
|
|
+ {
|
|
|
|
+ isRecvComplete = true;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+//Uart校验程序
|
|
|
|
+UINT16 crc_chk(UINT8* data, UINT8 length)
|
|
|
|
+{
|
|
|
|
+ UINT8 j;
|
|
|
|
+ UINT16 reg_crc=0xFFFF;
|
|
|
|
+ while(length--)
|
|
|
|
+ {
|
|
|
|
+ reg_crc ^= *data++;
|
|
|
|
+ for(j=0;j<8;j++)
|
|
|
|
+ {
|
|
|
|
+ if(reg_crc & 0x01)
|
|
|
|
+ {
|
|
|
|
+ reg_crc=(reg_crc>>1) ^ 0xA001;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ reg_crc=reg_crc >>1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return reg_crc;
|
|
|
|
+}
|
|
|
|
+//Uart写命令函数
|
|
|
|
+UINT8 Uart_WriteCmd_func(Uart_Write_Data_Type UartWriteData)
|
|
|
|
+{
|
|
|
|
+ Uart_Write_Msg_Type Uart_Write_Msg;
|
|
|
|
+ UINT16 RegAddress = 0x0000;
|
|
|
|
+ UINT16 CRC_chk_buffer;
|
|
|
|
+ UINT8 timeout = 0x00;
|
|
|
|
+ UINT8 Uart_Recv_Buffer[8];
|
|
|
|
+ switch (UartWriteData.WriteCmd)
|
|
|
|
+ {
|
|
|
|
+ case 0x01://是否锁定
|
|
|
|
+ {
|
|
|
|
+ RegAddress = 0x1B + BATT_CELL_VOL_NUM+BATT_TEMP_NUM+BATT_OTHER_TEMP_NUM;
|
|
|
|
+ Uart_Write_Msg.Bms_Address = BMS_ADDRESS_CODE;
|
|
|
|
+ Uart_Write_Msg.Bms_Funcode = UART_WRITE_CODE;
|
|
|
|
+ Uart_Write_Msg.Reg_Begin_H = RegAddress>>8;
|
|
|
|
+ Uart_Write_Msg.Reg_Begin_L = RegAddress;
|
|
|
|
+ Uart_Write_Msg.Reg_Num_H = 0x00;
|
|
|
|
+ Uart_Write_Msg.Reg_Num_L = 0x01;
|
|
|
|
+ Uart_Write_Msg.Data_Count = 0x02;//要写入的字节数
|
|
|
|
+ memcpy(Uart_Write_Msg.Data,UartWriteData.Data,2);
|
|
|
|
+ CRC_chk_buffer = crc_chk((UINT8 *)&Uart_Write_Msg,sizeof(Uart_Write_Msg)-2);
|
|
|
|
+ Uart_Write_Msg.CRC_L = CRC_chk_buffer;
|
|
|
|
+ Uart_Write_Msg.CRC_H = CRC_chk_buffer>>8;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case 0x02://是否加热
|
|
|
|
+ {
|
|
|
|
+ RegAddress = 0x1C + BATT_CELL_VOL_NUM+BATT_TEMP_NUM+BATT_OTHER_TEMP_NUM;
|
|
|
|
+ Uart_Write_Msg.Bms_Address = BMS_ADDRESS_CODE;
|
|
|
|
+ Uart_Write_Msg.Bms_Funcode = UART_WRITE_CODE;
|
|
|
|
+ Uart_Write_Msg.Reg_Begin_H = RegAddress>>8;
|
|
|
|
+ Uart_Write_Msg.Reg_Begin_L = RegAddress;
|
|
|
|
+ Uart_Write_Msg.Reg_Num_H = 0x00;
|
|
|
|
+ Uart_Write_Msg.Reg_Num_L = 0x01;
|
|
|
|
+ Uart_Write_Msg.Data_Count = 0x02;//要写入的字节数
|
|
|
|
+ memcpy(Uart_Write_Msg.Data,UartWriteData.Data,2);
|
|
|
|
+ CRC_chk_buffer = crc_chk((UINT8 *)&Uart_Write_Msg,sizeof(Uart_Write_Msg)-2);
|
|
|
|
+ Uart_Write_Msg.CRC_L = CRC_chk_buffer;
|
|
|
|
+ Uart_Write_Msg.CRC_H = CRC_chk_buffer>>8;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ default:
|
|
|
|
+ {
|
|
|
|
+ UartWriteData.WriteCmd = 0x00;
|
|
|
|
+ return 0;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ USARTdrv->Send((UINT8 *)&Uart_Write_Msg,sizeof(Uart_Write_Msg));
|
|
|
|
+ #ifdef USING_PRINTF1
|
|
|
|
+ printf("Uart_Send_buffer: ");
|
|
|
|
+ for(int i=0;i<sizeof(Uart_Write_Msg);i++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",*((UINT8 *)&Uart_Write_Msg+i));
|
|
|
|
+ }
|
|
|
|
+ printf("\n");
|
|
|
|
+ #endif
|
|
|
|
+ USARTdrv->Receive(Uart_Recv_Buffer,8);
|
|
|
|
+ while((isRecvTimeout == false) && (isRecvComplete == false))
|
|
|
|
+ {
|
|
|
|
+ timeout++;
|
|
|
|
+ osDelay(100);
|
|
|
|
+ if (timeout>=10)
|
|
|
|
+ {
|
|
|
|
+ timeout =0;
|
|
|
|
+ isRecvTimeout = true;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (isRecvComplete == true)
|
|
|
|
+ {
|
|
|
|
+ #ifdef USING_PRINTF1
|
|
|
|
+ printf("Uart_Rece_buffer: ");
|
|
|
|
+ for(int i=0;i<8;i++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",Uart_Recv_Buffer[i]);
|
|
|
|
+ }
|
|
|
|
+ printf("\n");
|
|
|
|
+ #endif
|
|
|
|
+ isRecvComplete = false;
|
|
|
|
+ if(Uart_Recv_Buffer[1]==0x10)
|
|
|
|
+ {
|
|
|
|
+ return UartWriteData.WriteCmd;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ return 0x00;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ isRecvTimeout = false;
|
|
|
|
+ return 0x00;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+//Uart发送接收函数
|
|
|
|
+UINT8 Uart_DataRecv_func(Uart_Read_Msg_Type Uart_Read_Msg_Fun,UINT8* Uart_Recv_Buffer_Fun)
|
|
|
|
+{
|
|
|
|
+ UINT16 CRC_Rece_buffer;
|
|
|
|
+ UINT16 CRC_chk_buffer;
|
|
|
|
+ UINT16 Data_Len ;
|
|
|
|
+ UINT8 timeout = 0x00;
|
|
|
|
+ UINT8 pSendCmd[8];
|
|
|
|
+ memcpy(pSendCmd,(UINT8*)(&Uart_Read_Msg_Fun),8);
|
|
|
|
+ //Data_Len = (*(Uart_Read_Msg_Fun+4)|*(Uart_Read_Msg_Fun+5))*2+5;
|
|
|
|
+ Data_Len = ((Uart_Read_Msg_Fun.Reg_Num_H<<8)|(Uart_Read_Msg_Fun.Reg_Num_L))*2+5;
|
|
|
|
+
|
|
|
|
+ //USARTdrv->Send(Uart_Read_Msg_Fun,8);
|
|
|
|
+ USARTdrv->Send(pSendCmd,8);
|
|
|
|
+ #ifdef USING_PRINTF1
|
|
|
|
+
|
|
|
|
+ printf("Uart_Send_buffer: ");
|
|
|
|
+ for(int i=0;i<8;i++)
|
|
|
|
+ // {
|
|
|
|
+ printf("%x ",pSendCmd[i]);
|
|
|
|
+ // }
|
|
|
|
+ printf("end\n");
|
|
|
|
+ //printf("%x ",*(Uart_Read_Msg_Fun));
|
|
|
|
+ //UINT8 temp = *(Uart_Read_Msg_Fun);
|
|
|
|
+ #endif
|
|
|
|
+ USARTdrv->Receive(Uart_Recv_Buffer_Fun,Data_Len);
|
|
|
|
+ while(true)
|
|
|
|
+ {
|
|
|
|
+ timeout++;
|
|
|
|
+ if((isRecvTimeout == true) || (isRecvComplete == true))
|
|
|
|
+ {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ osDelay(100);
|
|
|
|
+ if (timeout>=10)
|
|
|
|
+ {
|
|
|
|
+ // Data_Len = 0;
|
|
|
|
+ timeout =0;
|
|
|
|
+ isRecvTimeout = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ #ifdef USING_PRINTF1
|
|
|
|
+ printf("Uart_Rece_buffer1: ");
|
|
|
|
+ for(int j=0;j<Data_Len;j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",*(Uart_Recv_Buffer_Fun+j));
|
|
|
|
+ }
|
|
|
|
+ #endif
|
|
|
|
+ if (isRecvComplete == true)
|
|
|
|
+ {
|
|
|
|
+ isRecvComplete = false;
|
|
|
|
+ CRC_Rece_buffer =*(Uart_Recv_Buffer_Fun+Data_Len-1)<<8|*(Uart_Recv_Buffer_Fun+Data_Len-2);
|
|
|
|
+ CRC_chk_buffer = crc_chk(Uart_Recv_Buffer_Fun,Data_Len-2);
|
|
|
|
+ #ifdef USING_PRINTF1
|
|
|
|
+ printf("Uart_Rece_buffer after Crc: ");
|
|
|
|
+ for(int i=0;i<Data_Len;i++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",*(Uart_Recv_Buffer_Fun+i));
|
|
|
|
+ }
|
|
|
|
+ printf("\tcrcchk:%x,%x\n ",CRC_chk_buffer,CRC_Rece_buffer);
|
|
|
|
+ #endif
|
|
|
|
+ if (CRC_Rece_buffer == CRC_chk_buffer)//满足校验
|
|
|
|
+ {
|
|
|
|
+ return Data_Len;//此处指针移位出现重启问题
|
|
|
|
+ }
|
|
|
|
+ else //接收数据的校验不过
|
|
|
|
+ {
|
|
|
|
+ USARTdrv->Uninitialize();
|
|
|
|
+ osDelay(1000);
|
|
|
|
+ USARTdrv->Initialize(USART_callback);
|
|
|
|
+ USARTdrv->PowerControl(ARM_POWER_FULL);
|
|
|
|
+ USARTdrv->Control(ARM_USART_MODE_ASYNCHRONOUS |
|
|
|
|
+ ARM_USART_DATA_BITS_8 |
|
|
|
|
+ ARM_USART_PARITY_NONE |
|
|
|
|
+ ARM_USART_STOP_BITS_1 |
|
|
|
|
+ ARM_USART_FLOW_CONTROL_NONE, 9600);
|
|
|
|
+ memset(Uart_Recv_Buffer_Fun,0xff,Data_Len);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ memset(Uart_Recv_Buffer_Fun,0x00,Data_Len);
|
|
|
|
+ isRecvTimeout = false;
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ \fn BOOL BattHeaterSwitch(UINT8* heaterSwitch)
|
|
|
|
+ \param[in] (UINT8*) heaterSwitch: the heater switch state
|
|
|
|
+ \brief according to the current switch state and all the cell temp, it will turn on/off the switch
|
|
|
|
+ \return (BOOL) isNeedtoSwitch: true: need to send cmd to turn on/off the switch
|
|
|
|
+ false: do not need to do anything
|
|
|
|
+*/
|
|
|
|
+BOOL BattHeaterSwitch(UINT8* heaterSwitch)
|
|
|
|
+{
|
|
|
|
+ BOOL isNeedtoSwitch = FALSE;
|
|
|
|
+
|
|
|
|
+ UINT8 i =0;
|
|
|
|
+ UINT8 currentSwitchState = 0;
|
|
|
|
+ //get the current switch state and the cell temp
|
|
|
|
+ currentSwitchState = battMOSSwitchState & 0x01;
|
|
|
|
+ if(currentSwitchState==0) //当前状态为关闭,判断是否应该开启
|
|
|
|
+ {
|
|
|
|
+ if(minCellTemp<=5+40 && maxCellTemp<25+40 && battSOC>=12)//温度偏移为40
|
|
|
|
+ {
|
|
|
|
+ *heaterSwitch = 1;
|
|
|
|
+ isNeedtoSwitch = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else //当前状态为开启,判断是否应该关闭
|
|
|
|
+ {
|
|
|
|
+ if(minCellTemp>10+40 || maxCellTemp>30+40 || battSOC<10)
|
|
|
|
+ {
|
|
|
|
+ *heaterSwitch = 0;
|
|
|
|
+ isNeedtoSwitch= true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return isNeedtoSwitch;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void battSOCDisplay()
|
|
|
|
+{
|
|
|
|
+
|
|
|
|
+ static UINT8 lightTimer = 0;
|
|
|
|
+ UINT8 socLowLEDFlashPeriod = 10;//10*100 = 1000ms
|
|
|
|
+ UINT8 chargeLEDFlashPeriod = 6;//6*100 = 600ms
|
|
|
|
+ float dutyRatio = 0.4;
|
|
|
|
+ UINT8 temp;
|
|
|
|
+
|
|
|
|
+ if(AppNVMData.isBattLocked == TRUE)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if(UartBattInfoRecvFlag == true)
|
|
|
|
+ {
|
|
|
|
+ lightTimer++;
|
|
|
|
+
|
|
|
|
+ if(battWorkState == 0||battWorkState == 1) //静置或放电状态
|
|
|
|
+ {
|
|
|
|
+ if(battSOC<=10)
|
|
|
|
+ {
|
|
|
|
+ if(lightTimer<(UINT8)(socLowLEDFlashPeriod*dutyRatio))
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_2,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_3,LED_TURN_OFF);
|
|
|
|
+ }
|
|
|
|
+ else if(lightTimer>=(UINT8)(socLowLEDFlashPeriod*dutyRatio) && lightTimer<socLowLEDFlashPeriod)
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_2,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_3,LED_TURN_OFF);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_2,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_3,LED_TURN_OFF);
|
|
|
|
+ lightTimer = 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if(battSOC>10&&battSOC<=25)
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_2,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_3,LED_TURN_OFF);
|
|
|
|
+ lightTimer = 0;
|
|
|
|
+ }
|
|
|
|
+ else if(battSOC>25&&battSOC<=50)
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_2,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_3,LED_TURN_OFF);
|
|
|
|
+ lightTimer = 0;
|
|
|
|
+ }
|
|
|
|
+ else if(battSOC>50&&battSOC<=75)
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_2,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_3,LED_TURN_OFF);
|
|
|
|
+ lightTimer = 0;
|
|
|
|
+ }
|
|
|
|
+ else if(battSOC>75&&battSOC<=100)
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_2,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_3,LED_TURN_ON);
|
|
|
|
+ lightTimer = 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if(battWorkState == 2)
|
|
|
|
+ {
|
|
|
|
+ if(battSOC<=25)
|
|
|
|
+ {
|
|
|
|
+ if(lightTimer<(UINT8)(chargeLEDFlashPeriod*dutyRatio))
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_2,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_3,LED_TURN_OFF);
|
|
|
|
+ }
|
|
|
|
+ else if(lightTimer>=(UINT8)(chargeLEDFlashPeriod*dutyRatio) && lightTimer<chargeLEDFlashPeriod)
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_2,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_3,LED_TURN_OFF);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_2,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_3,LED_TURN_OFF);
|
|
|
|
+ lightTimer = 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if(battSOC>25&&battSOC<=50)
|
|
|
|
+ {
|
|
|
|
+ if(lightTimer<(UINT8)(chargeLEDFlashPeriod*dutyRatio))
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_2,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_3,LED_TURN_OFF);
|
|
|
|
+ }
|
|
|
|
+ else if(lightTimer>=(UINT8)(chargeLEDFlashPeriod*dutyRatio) && lightTimer<chargeLEDFlashPeriod)
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_2,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_3,LED_TURN_OFF);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_2,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_3,LED_TURN_OFF);
|
|
|
|
+ lightTimer = 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if(battSOC>50&&battSOC<=75)
|
|
|
|
+ {
|
|
|
|
+ if(lightTimer<(UINT8)(chargeLEDFlashPeriod*dutyRatio))
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_2,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_3,LED_TURN_OFF);
|
|
|
|
+ }
|
|
|
|
+ else if(lightTimer>=(UINT8)(chargeLEDFlashPeriod*dutyRatio) && lightTimer<chargeLEDFlashPeriod)
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_2,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_3,LED_TURN_OFF);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_2,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_3,LED_TURN_OFF);
|
|
|
|
+ lightTimer = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ else if(battSOC>75&&battSOC<=97)
|
|
|
|
+ {
|
|
|
|
+ if(lightTimer<(UINT8)(chargeLEDFlashPeriod*dutyRatio))
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_2,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_3,LED_TURN_ON);
|
|
|
|
+ }
|
|
|
|
+ else if(lightTimer>=(UINT8)(chargeLEDFlashPeriod*dutyRatio) && lightTimer<chargeLEDFlashPeriod)
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_2,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_3,LED_TURN_OFF);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_2,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_3,LED_TURN_OFF);
|
|
|
|
+ lightTimer = 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if(battSOC>97&&battSOC<=100)
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_2,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_3,LED_TURN_ON);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void battErrorStateDisplay()
|
|
|
|
+{
|
|
|
|
+ static UINT8 errorLightTimer = 0;
|
|
|
|
+ //static UINT32 currentTimerCount=0;
|
|
|
|
+
|
|
|
|
+ UINT8 errorLEDFlashPeriod = 6;//600ms
|
|
|
|
+ float errorDutyRatio = 0.4;
|
|
|
|
+
|
|
|
|
+ if(AppNVMData.isBattLocked == TRUE)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(UartBattInfoRecvFlag == true)
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ errorLightTimer++;
|
|
|
|
+
|
|
|
|
+ if(battWarningState != 0)
|
|
|
|
+ {
|
|
|
|
+ if(errorLightTimer<(UINT8)(errorLEDFlashPeriod*errorDutyRatio))
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ FaultDisplay(LED_TURN_ON);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ else if(errorLightTimer>=(UINT8)(errorLEDFlashPeriod*errorDutyRatio) && errorLightTimer<errorLEDFlashPeriod)
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ FaultDisplay(LED_TURN_OFF);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ FaultDisplay(LED_TURN_OFF);
|
|
|
|
+ errorLightTimer = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ FaultDisplay(LED_TURN_OFF);
|
|
|
|
+ errorLightTimer = 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void battWarningStateDisplay()
|
|
|
|
+{
|
|
|
|
+ static UINT8 warningLightTimer = 0;
|
|
|
|
+ //static UINT32 currentTimerCount=0;
|
|
|
|
+
|
|
|
|
+ UINT8 warningLEDFlashPeriod = 6;//600ms
|
|
|
|
+ float warningDutyRatio = 0.4;
|
|
|
|
+
|
|
|
|
+ if(AppNVMData.isBattLocked == TRUE)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(UartBattInfoRecvFlag == false)
|
|
|
|
+ {
|
|
|
|
+ warningLightTimer++;
|
|
|
|
+
|
|
|
|
+ //if(battWarningState != 0)
|
|
|
|
+ {
|
|
|
|
+ if(warningLightTimer<(UINT8)(warningLEDFlashPeriod*warningDutyRatio))
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_ON);
|
|
|
|
+ FaultDisplay(LED_TURN_ON);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ else if(warningLightTimer>=(UINT8)(warningLEDFlashPeriod*warningDutyRatio) && warningLightTimer<warningLEDFlashPeriod)
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_OFF);
|
|
|
|
+ FaultDisplay(LED_TURN_OFF);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_OFF);
|
|
|
|
+ FaultDisplay(LED_TURN_OFF);
|
|
|
|
+ warningLightTimer = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+void battLockStateDisplay(UINT8 lockState)
|
|
|
|
+{
|
|
|
|
+ static UINT8 currentState = 0;
|
|
|
|
+ static UINT8 errorLightTimer = 0;
|
|
|
|
+ //static UINT32 currentTimerCount=0;
|
|
|
|
+
|
|
|
|
+ UINT8 errorLEDFlashPeriod = 10;//1000ms
|
|
|
|
+ float errorDutyRatio = 0.4;
|
|
|
|
+
|
|
|
|
+ //printf("lockState = %d\ncurrent State = %d\n",lockState,currentState);
|
|
|
|
+ if(lockState==0)//no error
|
|
|
|
+ {
|
|
|
|
+ if(currentState!=lockState)
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_2,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_3,LED_TURN_OFF);
|
|
|
|
+ FaultDisplay(LED_TURN_OFF);
|
|
|
|
+ currentState = lockState;
|
|
|
|
+ errorLightTimer = 0;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ else // error occurred, errorState = 1
|
|
|
|
+ {
|
|
|
|
+ if(errorLightTimer<(UINT8)(errorLEDFlashPeriod*errorDutyRatio))
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_2,LED_TURN_ON);
|
|
|
|
+ NetSocDisplay(LED_SOC_3,LED_TURN_ON);
|
|
|
|
+ FaultDisplay(LED_TURN_ON);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ else if(errorLightTimer>=(UINT8)(errorLEDFlashPeriod*errorDutyRatio) && errorLightTimer<errorLEDFlashPeriod)
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_2,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_3,LED_TURN_OFF);
|
|
|
|
+ FaultDisplay(LED_TURN_OFF);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ NetSocDisplay(LED_SOC_0,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_2,LED_TURN_OFF);
|
|
|
|
+ NetSocDisplay(LED_SOC_3,LED_TURN_OFF);
|
|
|
|
+ FaultDisplay(LED_TURN_OFF);
|
|
|
|
+ errorLightTimer = 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ errorLightTimer++;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void relayPWMControl()
|
|
|
|
+{
|
|
|
|
+ static UINT8 timerCount=0;
|
|
|
|
+ //printf("timerCout=%d\n",timerCount);
|
|
|
|
+ if(timerCount<2)
|
|
|
|
+ {
|
|
|
|
+ relayControl(TRUE);
|
|
|
|
+ timerCount++;
|
|
|
|
+ }
|
|
|
|
+ else if(timerCount>=2 && timerCount<5)
|
|
|
|
+ {
|
|
|
|
+ relayControl(FALSE);
|
|
|
|
+ timerCount++;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ relayControl(FALSE);
|
|
|
|
+ timerCount = 0;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+UINT8 decryptionAlgorithm (UINT16 cipherText)
|
|
|
|
+{
|
|
|
|
+ UINT16 plainText = 1;
|
|
|
|
+ UINT16 publicKeyD = 43;
|
|
|
|
+ UINT16 publicKeyN = 10961;
|
|
|
|
+ cipherText = cipherText % publicKeyN;
|
|
|
|
+ while(publicKeyD >0)
|
|
|
|
+ {
|
|
|
|
+ if(publicKeyD % 2 ==1)
|
|
|
|
+ {
|
|
|
|
+ plainText = plainText * cipherText % publicKeyN;
|
|
|
|
+ }
|
|
|
|
+ publicKeyD = publicKeyD/2;
|
|
|
|
+ cipherText = (cipherText * cipherText) % publicKeyN;
|
|
|
|
+ }
|
|
|
|
+ return (UINT8)plainText;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+UINT16 encryptionAlgorithm (UINT16 plainText)
|
|
|
|
+{
|
|
|
|
+ UINT16 cipherText = 1;
|
|
|
|
+ UINT16 privateKeyE = 37507;
|
|
|
|
+ UINT16 privateKeyN = 10961;
|
|
|
|
+ plainText = plainText % privateKeyN;
|
|
|
|
+ while(privateKeyE >0)
|
|
|
|
+ {
|
|
|
|
+ if(privateKeyE % 2 ==1)
|
|
|
|
+ {
|
|
|
|
+ cipherText = ( cipherText * plainText) % privateKeyN;
|
|
|
|
+ }
|
|
|
|
+ privateKeyE = privateKeyE/2;
|
|
|
|
+ plainText = (plainText * plainText) % privateKeyN;
|
|
|
|
+ }
|
|
|
|
+ return cipherText;
|
|
|
|
+}
|
|
|
|
+UINT8 Uart_Encrypt_Send()
|
|
|
|
+{
|
|
|
|
+ UINT8 SeedNumberArrray[4]={0x38,0x56,0xfe,0xac};
|
|
|
|
+ UINT16 EncodeNumberArray[4];
|
|
|
|
+ UINT8 UartEncryptBuffer[17];
|
|
|
|
+ UINT8 UartDecryptBuffer[5];
|
|
|
|
+ UINT16 CRC_chk_buffer;
|
|
|
|
+ UINT8 timeCount = 0;
|
|
|
|
+ UartEncryptBuffer[0] = BMS_ADDRESS_CODE;
|
|
|
|
+ UartEncryptBuffer[1] = UART_ENCRYPT_CODE;
|
|
|
|
+ UartEncryptBuffer[2] = 0x0c;
|
|
|
|
+ for(int i=0;i<4;i++)
|
|
|
|
+ {
|
|
|
|
+ SeedNumberArrray[i]=rand();
|
|
|
|
+ EncodeNumberArray[i] = encryptionAlgorithm(SeedNumberArrray[i]);
|
|
|
|
+ UartEncryptBuffer[i+3] = SeedNumberArrray[i];
|
|
|
|
+ UartEncryptBuffer[i*2+7] = EncodeNumberArray[i]>>8;
|
|
|
|
+ UartEncryptBuffer[i*2+8] = EncodeNumberArray[i];
|
|
|
|
+ }
|
|
|
|
+ CRC_chk_buffer = crc_chk(UartEncryptBuffer,17-2);
|
|
|
|
+ UartEncryptBuffer[15] = CRC_chk_buffer;
|
|
|
|
+ UartEncryptBuffer[16] = CRC_chk_buffer>>8;
|
|
|
|
+ USARTdrv->Send(UartEncryptBuffer,17);
|
|
|
|
+ USARTdrv->Receive(UartDecryptBuffer,5);
|
|
|
|
+ while((isRecvTimeout == false) && (isRecvComplete == false))
|
|
|
|
+ {
|
|
|
|
+ timeCount++;
|
|
|
|
+ osDelay(100);
|
|
|
|
+ if (timeCount>=10)
|
|
|
|
+ {
|
|
|
|
+ timeCount =0;
|
|
|
|
+ isRecvTimeout = true;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ #ifdef USING_PRINTF
|
|
|
|
+ printf("Uart_Rece_buffer: ");
|
|
|
|
+ for(int i=0;i<5;i++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",UartDecryptBuffer[i]);
|
|
|
|
+ }
|
|
|
|
+ #endif
|
|
|
|
+ if (isRecvComplete == true)
|
|
|
|
+ {
|
|
|
|
+ isRecvComplete = false;
|
|
|
|
+ return UartDecryptBuffer[2];
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ isRecvTimeout = false;
|
|
|
|
+ return 0x03;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/*-----------------------------------------------------------------------------*/
|
|
|
|
+void SP_BMS_Update_Service() //超力源BMS升级服务
|
|
|
|
+{
|
|
|
|
+
|
|
|
|
+ UINT8 errorCount = 0;
|
|
|
|
+ UINT8 resetCount = 0;
|
|
|
|
+ UINT16 currentPackage = 0;
|
|
|
|
+ UINT32 updateDataTotalByteLen = 0;
|
|
|
|
+ UpdateStep updateStep = UPDATE_STEP_CHECK_VERSION;
|
|
|
|
+
|
|
|
|
+ UINT8 i,j,ret=0;
|
|
|
|
+ UINT8 dataLen = 0;
|
|
|
|
+
|
|
|
|
+ UINT8 pUpdateMsgSend[80];
|
|
|
|
+ UINT32 updateMsgSendLen = 0;
|
|
|
|
+ UINT32 currentPackageStartAddr = 0;
|
|
|
|
+ BMS_Update_Recv_Msg_Type pUpdateMsgRecv;
|
|
|
|
+ UINT8 bmsUpdateFlag = 1;
|
|
|
|
+ //BMS_Update_Recv_Msg_Type bmsMsg;
|
|
|
|
+ //static UpdateStep step = UPDATE_STEP_CHECK_VERSION;
|
|
|
|
+ UINT8 Cycle_conut = 0;
|
|
|
|
+ while(bmsUpdateFlag && Cycle_conut<2)
|
|
|
|
+ {
|
|
|
|
+ switch (updateStep)
|
|
|
|
+ {
|
|
|
|
+ case UPDATE_STEP_CHECK_VERSION:
|
|
|
|
+
|
|
|
|
+ dataLen = 0;
|
|
|
|
+ updateMsgSendLen = 7;
|
|
|
|
+ pUpdateMsgSend[0] = 0xEB; //start flag
|
|
|
|
+ pUpdateMsgSend[1] = 0x01; //add flag
|
|
|
|
+ pUpdateMsgSend[2] = 0x01; //read
|
|
|
|
+ pUpdateMsgSend[3] = 0x03; //data len
|
|
|
|
+ pUpdateMsgSend[4] = 0x90; //cmd
|
|
|
|
+ pUpdateMsgSend[5] = 0x93; //checksum
|
|
|
|
+ pUpdateMsgSend[6] = 0xF5; //end flag
|
|
|
|
+ //printf("updateMsgSendLen0 = %x\n",updateMsgSendLen);
|
|
|
|
+ memset((UINT8*)(&pUpdateMsgRecv) , 0, sizeof(BMS_Update_Recv_Msg_Type));
|
|
|
|
+ ret = SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(&pUpdateMsgRecv),sizeof(BMS_Update_Recv_Msg_Type), 500);
|
|
|
|
+ //printf("updateMsgSendLen1 = %x\n",updateMsgSendLen);
|
|
|
|
+ if(ret!=0)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.startFlag == 0xEB && pUpdateMsgRecv.endFlag == 0xF5)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.cmd == 0x90)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.data != 0xFF)
|
|
|
|
+ {
|
|
|
|
+ updateStep = UPDATE_STEP_REQUEST_UPDATE;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ updateStep = UPDATE_STEP_SET_BAUD_RATE;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ #ifdef USING_PRINTF1
|
|
|
|
+ //printf("update step:%d\n",updateStep);
|
|
|
|
+ printf("query:");
|
|
|
|
+
|
|
|
|
+ for(j=0;j<updateMsgSendLen;j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",pUpdateMsgSend[j]);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ printf("\nanswer:");
|
|
|
|
+ for(j=0;j<sizeof(BMS_Update_Recv_Msg_Type);j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",*(((UINT8*)&pUpdateMsgRecv)+j));
|
|
|
|
+ }
|
|
|
|
+ printf("\n");
|
|
|
|
+ printf("next update step:%d\n",updateStep);
|
|
|
|
+ #endif
|
|
|
|
+ if(errorCount>10)
|
|
|
|
+ {
|
|
|
|
+ updateStep = UPDATE_STEP_RESET;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+ osDelay(50);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case UPDATE_STEP_REQUEST_UPDATE:
|
|
|
|
+ dataLen = 1;
|
|
|
|
+ updateMsgSendLen = 8;
|
|
|
|
+ pUpdateMsgSend[0] = 0xEB; //start flag
|
|
|
|
+ pUpdateMsgSend[1] = 0x01; //add flag
|
|
|
|
+ pUpdateMsgSend[2] = 0x00; //write
|
|
|
|
+ pUpdateMsgSend[3] = 0x04; //data len
|
|
|
|
+ pUpdateMsgSend[4] = 0x80; //cmd
|
|
|
|
+ pUpdateMsgSend[5] = 0x22; //data
|
|
|
|
+ pUpdateMsgSend[6] = 0xA6; //check
|
|
|
|
+ pUpdateMsgSend[7] = 0xF5; //end flag
|
|
|
|
+ memset((UINT8*)(&pUpdateMsgRecv) , 0, sizeof(BMS_Update_Recv_Msg_Type));
|
|
|
|
+ ret = SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(&pUpdateMsgRecv), sizeof(BMS_Update_Recv_Msg_Type), 500);
|
|
|
|
+ if(ret!=0)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.startFlag == 0xEB && pUpdateMsgRecv.endFlag == 0xF5)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.cmd == 0x80)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.data == 0x33)
|
|
|
|
+ {
|
|
|
|
+ updateStep = UPDATE_STEP_START_UPDATE;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(errorCount>10)
|
|
|
|
+ {
|
|
|
|
+ updateStep = UPDATE_STEP_RESET;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #ifdef USING_PRINTF1
|
|
|
|
+ printf("update step:%d\n",updateStep);
|
|
|
|
+ printf("query:");
|
|
|
|
+ for(j=0;j<updateMsgSendLen;j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",pUpdateMsgSend[j]);
|
|
|
|
+ }
|
|
|
|
+ printf("\nanswer:");
|
|
|
|
+ for(j=0;j<sizeof(BMS_Update_Recv_Msg_Type);j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",*(((UINT8*)&pUpdateMsgRecv)+j));
|
|
|
|
+ }
|
|
|
|
+ printf("\n");
|
|
|
|
+ printf("next update step:%d\n",updateStep);
|
|
|
|
+ #endif
|
|
|
|
+ osDelay(50);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case UPDATE_STEP_START_UPDATE:
|
|
|
|
+ dataLen = 1;
|
|
|
|
+ updateMsgSendLen = 8;
|
|
|
|
+ pUpdateMsgSend[0] = 0xEB; //start flag
|
|
|
|
+ pUpdateMsgSend[1] = 0x01; //add flag
|
|
|
|
+ pUpdateMsgSend[2] = 0x00; //write
|
|
|
|
+ pUpdateMsgSend[3] = 0x04; //data len
|
|
|
|
+ pUpdateMsgSend[4] = 0x80; //cmd
|
|
|
|
+ pUpdateMsgSend[5] = 0x55; //data
|
|
|
|
+ pUpdateMsgSend[6] = 0xD9; //check
|
|
|
|
+ pUpdateMsgSend[7] = 0xF5; //end flag
|
|
|
|
+ memset((UINT8*)(&pUpdateMsgRecv) , 0, sizeof(BMS_Update_Recv_Msg_Type));
|
|
|
|
+ ret = SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(&pUpdateMsgRecv), 0, 500);
|
|
|
|
+ //updateStep = UPDATE_STEP_SET_BAUD_RATE;
|
|
|
|
+ updateStep = UPDATE_STEP_CHECK_VERSION_AGAIN;//2021-04-09跳过波特率设置
|
|
|
|
+ #ifdef USING_PRINTF1
|
|
|
|
+
|
|
|
|
+ printf("query:");
|
|
|
|
+ for(j=0;j<updateMsgSendLen;j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",pUpdateMsgSend[j]);
|
|
|
|
+ }
|
|
|
|
+ printf("\nanswer:");
|
|
|
|
+ for(j=0;j<sizeof(BMS_Update_Recv_Msg_Type);j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",*(((UINT8*)&pUpdateMsgRecv)+j));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ printf("\n");
|
|
|
|
+ printf("next update step:%d\n",updateStep);
|
|
|
|
+ #endif
|
|
|
|
+ break;
|
|
|
|
+ case UPDATE_STEP_CHECK_VERSION_AGAIN:
|
|
|
|
+ dataLen = 0;
|
|
|
|
+ updateMsgSendLen = 7;
|
|
|
|
+ pUpdateMsgSend[0] = 0xEB; //start flag
|
|
|
|
+ pUpdateMsgSend[1] = 0x01; //add flag
|
|
|
|
+ pUpdateMsgSend[2] = 0x01; //read
|
|
|
|
+ pUpdateMsgSend[3] = 0x03; //data len
|
|
|
|
+ pUpdateMsgSend[4] = 0x90; //cmd
|
|
|
|
+ pUpdateMsgSend[5] = 0x93; //checksum
|
|
|
|
+ pUpdateMsgSend[6] = 0xF5; //end flag
|
|
|
|
+ //printf("updateMsgSendLen0 = %x\n",updateMsgSendLen);
|
|
|
|
+ memset((UINT8*)(&pUpdateMsgRecv) , 0, sizeof(BMS_Update_Recv_Msg_Type));
|
|
|
|
+ ret = SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(&pUpdateMsgRecv),sizeof(BMS_Update_Recv_Msg_Type), 100);
|
|
|
|
+ //printf("updateMsgSendLen1 = %x\n",updateMsgSendLen);
|
|
|
|
+ if(ret!=0)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.startFlag == 0xEB && pUpdateMsgRecv.endFlag == 0xF5)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.cmd == 0x90)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.data != 0xFF)
|
|
|
|
+ {
|
|
|
|
+ updateStep = UPDATE_STEP_RESET;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ updateStep = UPDATE_STEP_SET_BAUD_RATE;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ #ifdef USING_PRINTF1
|
|
|
|
+ //printf("update step:%d\n",updateStep);
|
|
|
|
+ printf("query:");
|
|
|
|
+
|
|
|
|
+ for(j=0;j<updateMsgSendLen;j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",pUpdateMsgSend[j]);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ printf("\nanswer:");
|
|
|
|
+ for(j=0;j<sizeof(BMS_Update_Recv_Msg_Type);j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",*(((UINT8*)&pUpdateMsgRecv)+j));
|
|
|
|
+ }
|
|
|
|
+ printf("\n");
|
|
|
|
+ printf("next update step:%d\n",updateStep);
|
|
|
|
+ #endif
|
|
|
|
+ if(errorCount>10)
|
|
|
|
+ {
|
|
|
|
+ updateStep = UPDATE_STEP_RESET;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+ osDelay(50);
|
|
|
|
+ break;
|
|
|
|
+ case UPDATE_STEP_SET_BAUD_RATE:
|
|
|
|
+ printf("start step %d\n",updateStep);
|
|
|
|
+ dataLen = 4;
|
|
|
|
+ updateMsgSendLen = 12;
|
|
|
|
+ pUpdateMsgSend[0] = 0xEB; //start flag
|
|
|
|
+ pUpdateMsgSend[1] = 0x01; //add flag
|
|
|
|
+ pUpdateMsgSend[2] = 0x00; //write
|
|
|
|
+ pUpdateMsgSend[3] = 0x08; //data len
|
|
|
|
+ pUpdateMsgSend[4] = 0x81; //cmd
|
|
|
|
+ pUpdateMsgSend[5] = 0x33; //data
|
|
|
|
+ pUpdateMsgSend[6] = 0x00; //baud rate:9600
|
|
|
|
+ pUpdateMsgSend[7] = 0x00;
|
|
|
|
+ pUpdateMsgSend[8] = 0x25;
|
|
|
|
+ pUpdateMsgSend[9] = 0x80;
|
|
|
|
+ pUpdateMsgSend[10] = 0x61; //check
|
|
|
|
+ pUpdateMsgSend[11] = 0xF5; //end flag
|
|
|
|
+ #ifdef USING_PRINTF1
|
|
|
|
+ printf("query:");
|
|
|
|
+ for(j=0;j<updateMsgSendLen;j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",pUpdateMsgSend[j]);
|
|
|
|
+ }
|
|
|
|
+ printf("\n");
|
|
|
|
+ #endif
|
|
|
|
+ memset((UINT8*)(&pUpdateMsgRecv) , 0, sizeof(BMS_Update_Recv_Msg_Type));
|
|
|
|
+ ret = SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(&pUpdateMsgRecv), sizeof(BMS_Update_Recv_Msg_Type), 500);
|
|
|
|
+ printf("ret = %d\n",ret);
|
|
|
|
+ if(ret!=0)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.startFlag == 0xEB && pUpdateMsgRecv.endFlag == 0xF5)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.cmd == 0x81)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.data == 0x11)
|
|
|
|
+ {
|
|
|
|
+ updateStep = UPDATE_STEP_PREPARE_SEND_DATA_LEN;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(errorCount>10)
|
|
|
|
+ {
|
|
|
|
+ updateStep = UPDATE_STEP_RESET;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #ifdef USING_PRINTF1
|
|
|
|
+ //printf("update step:%d\n",updateStep);
|
|
|
|
+ printf("query:");
|
|
|
|
+ for(j=0;j<updateMsgSendLen;j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",pUpdateMsgSend[j]);
|
|
|
|
+ }
|
|
|
|
+ printf("\nanswer:");
|
|
|
|
+ for(j=0;j<sizeof(BMS_Update_Recv_Msg_Type);j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",*(((UINT8*)&pUpdateMsgRecv)+j));
|
|
|
|
+ }
|
|
|
|
+ printf("\n");
|
|
|
|
+ printf("next update step:%d\n",updateStep);
|
|
|
|
+ #endif
|
|
|
|
+ osDelay(50);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ case UPDATE_STEP_PREPARE_SEND_DATA_LEN:
|
|
|
|
+ printf("start step %d\n",updateStep);
|
|
|
|
+ dataLen = 1;
|
|
|
|
+ updateMsgSendLen = 8;
|
|
|
|
+ pUpdateMsgSend[0] = 0xEB; //start flag
|
|
|
|
+ pUpdateMsgSend[1] = 0x01; //add flag
|
|
|
|
+ pUpdateMsgSend[2] = 0x00; //write
|
|
|
|
+ pUpdateMsgSend[3] = 0x04; //data len
|
|
|
|
+ pUpdateMsgSend[4] = 0x81; //cmd
|
|
|
|
+ pUpdateMsgSend[5] = 0x44; //data
|
|
|
|
+ pUpdateMsgSend[6] = 0xC9; //check
|
|
|
|
+ pUpdateMsgSend[7] = 0xF5; //end flag
|
|
|
|
+ memset((UINT8*)(&pUpdateMsgRecv) , 0, sizeof(BMS_Update_Recv_Msg_Type));
|
|
|
|
+ ret = SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(&pUpdateMsgRecv), sizeof(BMS_Update_Recv_Msg_Type), 500);
|
|
|
|
+ if(ret!=0)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.startFlag == 0xEB && pUpdateMsgRecv.endFlag == 0xF5)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.cmd == 0x81)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.data == 0x11)
|
|
|
|
+ {
|
|
|
|
+ updateStep = UPDATE_STEP_SEND_DATA_LEN;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(errorCount>10)
|
|
|
|
+ {
|
|
|
|
+ updateStep = UPDATE_STEP_RESET;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #ifdef USING_PRINTF1
|
|
|
|
+ //printf("update step:%d\n",updateStep);
|
|
|
|
+ printf("query:");
|
|
|
|
+ for(j=0;j<updateMsgSendLen;j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",pUpdateMsgSend[j]);
|
|
|
|
+ }
|
|
|
|
+ printf("\nanswer:");
|
|
|
|
+ for(j=0;j<sizeof(BMS_Update_Recv_Msg_Type);j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",*(((UINT8*)&pUpdateMsgRecv)+j));
|
|
|
|
+ }
|
|
|
|
+ printf("\n");
|
|
|
|
+ printf("next update step:%d\n",updateStep);
|
|
|
|
+ #endif
|
|
|
|
+ osDelay(50);
|
|
|
|
+ break;
|
|
|
|
+ case UPDATE_STEP_SEND_DATA_LEN:
|
|
|
|
+
|
|
|
|
+ dataLen = 4;
|
|
|
|
+ BSP_QSPI_Read_Safe(&updateDataTotalByteLen,FLASH_BMS_FOTA_START_ADDR,4);
|
|
|
|
+ updateDataTotalByteLen = (((updateDataTotalByteLen)&0xFF)<<24)|(((updateDataTotalByteLen>>8)&0xFF)<<16)|(((updateDataTotalByteLen>>16)&0xFF)<<8)|(((updateDataTotalByteLen>>24)&0xFF));
|
|
|
|
+ updateMsgSendLen = 11;
|
|
|
|
+ pUpdateMsgSend[0] = 0xEB; //start flag
|
|
|
|
+ pUpdateMsgSend[1] = 0x01; //add flag
|
|
|
|
+ pUpdateMsgSend[2] = 0x00; //write
|
|
|
|
+ pUpdateMsgSend[3] = 0x07; //data len
|
|
|
|
+ pUpdateMsgSend[4] = 0x82; //cmd
|
|
|
|
+ pUpdateMsgSend[5] = (updateDataTotalByteLen>>24)&0xFF; //data: package byte len
|
|
|
|
+ pUpdateMsgSend[6] = (updateDataTotalByteLen>>16)&0xFF;
|
|
|
|
+ pUpdateMsgSend[7] = (updateDataTotalByteLen>>8)&0xFF;
|
|
|
|
+ pUpdateMsgSend[8] = (updateDataTotalByteLen)&0xFF;
|
|
|
|
+ pUpdateMsgSend[9] = SP_BMS_Update_CheckSUM(&pUpdateMsgSend[3], dataLen+2); //check sum
|
|
|
|
+ pUpdateMsgSend[10] = 0xF5; //end flag
|
|
|
|
+
|
|
|
|
+ memset((UINT8*)(&pUpdateMsgRecv),0,sizeof(BMS_Update_Recv_Msg_Type));
|
|
|
|
+ ret = SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(&pUpdateMsgRecv), sizeof(BMS_Update_Recv_Msg_Type), 500);
|
|
|
|
+ if(ret!=0)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.startFlag == 0xEB && pUpdateMsgRecv.endFlag == 0xF5)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.cmd == 0x81)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.data == 0x11)
|
|
|
|
+ {
|
|
|
|
+ updateStep = UPDATE_STEP_PREPARE_SEND_UPDATE_DATA;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(errorCount>10)
|
|
|
|
+ {
|
|
|
|
+ updateStep = UPDATE_STEP_RESET;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #ifdef USING_PRINTF1
|
|
|
|
+ //printf("update step:%d\n",updateStep);
|
|
|
|
+ printf("query:");
|
|
|
|
+ for(j=0;j<updateMsgSendLen;j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",pUpdateMsgSend[j]);
|
|
|
|
+ }
|
|
|
|
+ printf("\nanswer:");
|
|
|
|
+ for(j=0;j<sizeof(BMS_Update_Recv_Msg_Type);j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",*(((UINT8*)&pUpdateMsgRecv)+j));
|
|
|
|
+ }
|
|
|
|
+ printf("\n");
|
|
|
|
+ printf("next update step:%d\n",updateStep);
|
|
|
|
+ #endif
|
|
|
|
+ osDelay(50);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case UPDATE_STEP_PREPARE_SEND_UPDATE_DATA:
|
|
|
|
+ dataLen = 1;
|
|
|
|
+ updateMsgSendLen = 8;
|
|
|
|
+ pUpdateMsgSend[0] = 0xEB; //start flag
|
|
|
|
+ pUpdateMsgSend[1] = 0x01; //add flag
|
|
|
|
+ pUpdateMsgSend[2] = 0x00; //write
|
|
|
|
+ pUpdateMsgSend[3] = 0x04; //data len
|
|
|
|
+ pUpdateMsgSend[4] = 0x81; //cmd
|
|
|
|
+ pUpdateMsgSend[5] = 0x55; //data
|
|
|
|
+ pUpdateMsgSend[6] = 0xDA; //check
|
|
|
|
+ pUpdateMsgSend[7] = 0xF5; //end flag
|
|
|
|
+ memset((UINT8*)(&pUpdateMsgRecv) , 0, sizeof(BMS_Update_Recv_Msg_Type));
|
|
|
|
+ ret = SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen,(UINT8*)(&pUpdateMsgRecv), sizeof(BMS_Update_Recv_Msg_Type), 500);
|
|
|
|
+ if(ret!=0)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.startFlag == 0xEB && pUpdateMsgRecv.endFlag == 0xF5)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.cmd == 0x81)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.data == 0x11)
|
|
|
|
+ {
|
|
|
|
+ updateStep = UPDATE_STEP_SEND_UPDATE_DATA;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(errorCount>10)
|
|
|
|
+ {
|
|
|
|
+ updateStep = UPDATE_STEP_RESET;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #ifdef USING_PRINTF1
|
|
|
|
+ //printf("update step:%d\n",updateStep);
|
|
|
|
+ printf("query:");
|
|
|
|
+ for(j=0;j<updateMsgSendLen;j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",pUpdateMsgSend[j]);
|
|
|
|
+ }
|
|
|
|
+ printf("\nanswer:");
|
|
|
|
+ for(j=0;j<sizeof(BMS_Update_Recv_Msg_Type);j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",*(((UINT8*)&pUpdateMsgRecv)+j));
|
|
|
|
+ }
|
|
|
|
+ printf("\n");
|
|
|
|
+ printf("next update step:%d\n",updateStep);
|
|
|
|
+ #endif
|
|
|
|
+ osDelay(50);
|
|
|
|
+ break;
|
|
|
|
+ case UPDATE_STEP_SEND_UPDATE_DATA:
|
|
|
|
+ dataLen = 64;
|
|
|
|
+ updateMsgSendLen = 75;
|
|
|
|
+
|
|
|
|
+ for(currentPackage=0;currentPackage<updateDataTotalByteLen/64;currentPackage++)
|
|
|
|
+ {
|
|
|
|
+ currentPackageStartAddr = currentPackage*64;
|
|
|
|
+
|
|
|
|
+ pUpdateMsgSend[0] = 0xEB; //start flag
|
|
|
|
+ pUpdateMsgSend[1] = 0x01; //add flag
|
|
|
|
+ pUpdateMsgSend[2] = 0x00; //write
|
|
|
|
+ pUpdateMsgSend[3] = 0x47; //data len
|
|
|
|
+ pUpdateMsgSend[4] = 0x82; //cmd
|
|
|
|
+ pUpdateMsgSend[5] = (currentPackageStartAddr>>24)&0xFF;
|
|
|
|
+ pUpdateMsgSend[6] = (currentPackageStartAddr>>16)&0xFF;
|
|
|
|
+ pUpdateMsgSend[7] = (currentPackageStartAddr>>8)&0xFF;
|
|
|
|
+ pUpdateMsgSend[8] = currentPackageStartAddr&0xFF;
|
|
|
|
+ BSP_QSPI_Read_Safe(&pUpdateMsgSend[9], FLASH_BMS_FOTA_START_ADDR+4+currentPackage*dataLen, dataLen); //data
|
|
|
|
+ pUpdateMsgSend[8+dataLen+1] = SP_BMS_Update_CheckSUM(&pUpdateMsgSend[3], dataLen+6); //check sum
|
|
|
|
+ pUpdateMsgSend[8+dataLen+2] = 0xF5; //end flag
|
|
|
|
+ memset((UINT8*)(&pUpdateMsgRecv) , 0, sizeof(BMS_Update_Recv_Msg_Type));
|
|
|
|
+ ret = SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(&pUpdateMsgRecv), sizeof(BMS_Update_Recv_Msg_Type), 500);
|
|
|
|
+ if(ret!=0)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.startFlag == 0xEB && pUpdateMsgRecv.endFlag == 0xF5)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.cmd == 0x81)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.data == 0x11)
|
|
|
|
+ {
|
|
|
|
+ if(currentPackage+1 == updateDataTotalByteLen/64)
|
|
|
|
+ {
|
|
|
|
+ updateStep = UPDATE_STEP_SEND_DATA_END;
|
|
|
|
+ }
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(errorCount>10)
|
|
|
|
+ {
|
|
|
|
+ updateStep = UPDATE_STEP_RESET;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ #ifdef USING_PRINTF1
|
|
|
|
+ //printf("update step:%d\n",updateStep);
|
|
|
|
+ printf("query:");
|
|
|
|
+ for(j=0;j<updateMsgSendLen;j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",pUpdateMsgSend[j]);
|
|
|
|
+ }
|
|
|
|
+ printf("\nanswer:");
|
|
|
|
+ for(j=0;j<sizeof(BMS_Update_Recv_Msg_Type);j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",*(((UINT8*)&pUpdateMsgRecv)+j));
|
|
|
|
+ }
|
|
|
|
+ printf("\n");
|
|
|
|
+ printf("next update step:%d\n",updateStep);
|
|
|
|
+ #endif
|
|
|
|
+ }
|
|
|
|
+ osDelay(50);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case UPDATE_STEP_SEND_DATA_END:
|
|
|
|
+ dataLen = 1;
|
|
|
|
+ updateMsgSendLen = 8;
|
|
|
|
+ pUpdateMsgSend[0] = 0xEB; //start flag
|
|
|
|
+ pUpdateMsgSend[1] = 0x01; //add flag
|
|
|
|
+ pUpdateMsgSend[2] = 0x00; //write
|
|
|
|
+ pUpdateMsgSend[3] = 0x04; //data len
|
|
|
|
+ pUpdateMsgSend[4] = 0x81; //cmd
|
|
|
|
+ pUpdateMsgSend[5] = 0x66; //data
|
|
|
|
+ pUpdateMsgSend[6] = 0xEB; //check
|
|
|
|
+ pUpdateMsgSend[7] = 0xF5; //end flag
|
|
|
|
+ memset((UINT8*)(&pUpdateMsgRecv) , 0, sizeof(BMS_Update_Recv_Msg_Type));
|
|
|
|
+ ret = SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(&pUpdateMsgRecv), sizeof(BMS_Update_Recv_Msg_Type), 500);
|
|
|
|
+ if(ret!=0)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.startFlag == 0xEB && pUpdateMsgRecv.endFlag == 0xF5)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.cmd == 0x81)
|
|
|
|
+ {
|
|
|
|
+ if(pUpdateMsgRecv.data == 0x11)
|
|
|
|
+ {
|
|
|
|
+ updateStep = UPDATE_STEP_START_INSTALL;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(errorCount>10)
|
|
|
|
+ {
|
|
|
|
+ updateStep = UPDATE_STEP_RESET;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #ifdef USING_PRINTF1
|
|
|
|
+ //printf("update step:%d\n",updateStep);
|
|
|
|
+ printf("query:");
|
|
|
|
+ for(j=0;j<updateMsgSendLen;j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",pUpdateMsgSend[j]);
|
|
|
|
+ }
|
|
|
|
+ printf("\nanswer:");
|
|
|
|
+ for(j=0;j<sizeof(BMS_Update_Recv_Msg_Type);j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",*(((UINT8*)&pUpdateMsgRecv)+j));
|
|
|
|
+ }
|
|
|
|
+ printf("\n");
|
|
|
|
+ printf("next update step:%d\n",updateStep);
|
|
|
|
+ #endif
|
|
|
|
+ osDelay(50);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case UPDATE_STEP_START_INSTALL:
|
|
|
|
+ dataLen = 1;
|
|
|
|
+ updateMsgSendLen = 8;
|
|
|
|
+ pUpdateMsgSend[0] = 0xEB; //start flag
|
|
|
|
+ pUpdateMsgSend[1] = 0x01; //add flag
|
|
|
|
+ pUpdateMsgSend[2] = 0x00; //write
|
|
|
|
+ pUpdateMsgSend[3] = 0x04; //data len
|
|
|
|
+ pUpdateMsgSend[4] = 0x81; //cmd
|
|
|
|
+ pUpdateMsgSend[5] = 0x99; //data
|
|
|
|
+ pUpdateMsgSend[6] = 0x1E; //check
|
|
|
|
+ pUpdateMsgSend[7] = 0xF5; //end flag
|
|
|
|
+ memset((UINT8*)(&pUpdateMsgRecv) , 0, sizeof(BMS_Update_Recv_Msg_Type));
|
|
|
|
+ SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(&pUpdateMsgRecv), 0, 500);
|
|
|
|
+
|
|
|
|
+ updateStep = UPDATE_STEP_END;
|
|
|
|
+
|
|
|
|
+ #ifdef USING_PRINTF1
|
|
|
|
+ //printf("update step:%d\n",updateStep);
|
|
|
|
+ printf("query:");
|
|
|
|
+ for(j=0;j<updateMsgSendLen;j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",pUpdateMsgSend[j]);
|
|
|
|
+ }
|
|
|
|
+ printf("\nanswer:");
|
|
|
|
+ for(j=0;j<sizeof(BMS_Update_Recv_Msg_Type);j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",*(((UINT8*)&pUpdateMsgRecv)+j));
|
|
|
|
+ }
|
|
|
|
+ printf("\n");
|
|
|
|
+ printf("next update step:%d\n",updateStep);
|
|
|
|
+ #endif
|
|
|
|
+ osDelay(50);
|
|
|
|
+ break;
|
|
|
|
+ case UPDATE_STEP_END:
|
|
|
|
+ updateStep = UPDATE_STEP_CHECK_VERSION;
|
|
|
|
+ printf("update end\n");
|
|
|
|
+ bmsUpdateFlag = 0;
|
|
|
|
+ break;
|
|
|
|
+ case UPDATE_STEP_RESET:
|
|
|
|
+ dataLen = 1;
|
|
|
|
+ updateMsgSendLen = 8;
|
|
|
|
+ pUpdateMsgSend[0] = 0xEB; //start flag
|
|
|
|
+ pUpdateMsgSend[1] = 0x01; //add flag
|
|
|
|
+ pUpdateMsgSend[2] = 0x00; //write
|
|
|
|
+ pUpdateMsgSend[3] = 0x04; //data len
|
|
|
|
+ pUpdateMsgSend[4] = 0x81; //cmd
|
|
|
|
+ pUpdateMsgSend[5] = 0xAA; //data
|
|
|
|
+ pUpdateMsgSend[6] = 0x2F; //check
|
|
|
|
+ pUpdateMsgSend[7] = 0xF5; //end flag
|
|
|
|
+ memset((UINT8*)(&pUpdateMsgRecv) , 0, sizeof(BMS_Update_Recv_Msg_Type));
|
|
|
|
+ SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(&pUpdateMsgRecv), 0, 500);
|
|
|
|
+ osDelay(50);
|
|
|
|
+
|
|
|
|
+ resetCount++;
|
|
|
|
+ if(resetCount>=2)
|
|
|
|
+ {
|
|
|
|
+ updateStep = UPDATE_STEP_DOWNLOAD_BREAK_OFF;
|
|
|
|
+ resetCount = 0;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ updateStep = UPDATE_STEP_PREPARE_SEND_DATA_LEN;
|
|
|
|
+ }
|
|
|
|
+ #ifdef USING_PRINTF
|
|
|
|
+ printf("update error!!\n rest and start send data lenth again!!\n continue update!\n");
|
|
|
|
+ #endif
|
|
|
|
+ break;
|
|
|
|
+ case UPDATE_STEP_DOWNLOAD_BREAK_OFF:
|
|
|
|
+ dataLen = 1;
|
|
|
|
+ updateMsgSendLen = 8;
|
|
|
|
+ pUpdateMsgSend[0] = 0xEB; //start flag
|
|
|
|
+ pUpdateMsgSend[1] = 0x01; //add flag
|
|
|
|
+ pUpdateMsgSend[2] = 0x00; //write
|
|
|
|
+ pUpdateMsgSend[3] = 0x04; //data len
|
|
|
|
+ pUpdateMsgSend[4] = 0x81; //cmd
|
|
|
|
+ pUpdateMsgSend[5] = 0xBB; //data
|
|
|
|
+ pUpdateMsgSend[6] = 0x40; //check
|
|
|
|
+ pUpdateMsgSend[7] = 0xF5; //end flag
|
|
|
|
+ memset((UINT8*)(&pUpdateMsgRecv) , 0, sizeof(BMS_Update_Recv_Msg_Type));
|
|
|
|
+ SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(&pUpdateMsgRecv), 0, 500);
|
|
|
|
+ osDelay(50);
|
|
|
|
+ updateStep = UPDATE_STEP_CHECK_VERSION;
|
|
|
|
+ Cycle_conut++;
|
|
|
|
+ break;
|
|
|
|
+ case UPDATE_STEP_ERROR:
|
|
|
|
+ updateStep = UPDATE_STEP_CHECK_VERSION;
|
|
|
|
+ printf("update error end\n");
|
|
|
|
+ bmsUpdateFlag = 0;
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ default:
|
|
|
|
+ updateStep = UPDATE_STEP_CHECK_VERSION;
|
|
|
|
+ printf("update default end\n");
|
|
|
|
+ bmsUpdateFlag = 0;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+UINT8 SP_BMS_Update_Query(UINT8* pSend,UINT32 sendLen, UINT8* pRead, UINT32 readLen, UINT32 timeout)
|
|
|
|
+{
|
|
|
|
+
|
|
|
|
+ UINT8 timeCount = 0;
|
|
|
|
+ UINT8 j=0;
|
|
|
|
+ USARTdrv->Send(pSend,sendLen);
|
|
|
|
+ #ifdef USING_PRINTF
|
|
|
|
+ printf("query in:");
|
|
|
|
+ for(j=0;j<sendLen;j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",*(pSend+j));
|
|
|
|
+ }
|
|
|
|
+ printf("\n");
|
|
|
|
+ #endif
|
|
|
|
+ if(readLen>0)
|
|
|
|
+ {
|
|
|
|
+ USARTdrv->Receive(pRead,readLen);
|
|
|
|
+ while((isRecvTimeout == false) && (isRecvComplete == false))
|
|
|
|
+ {
|
|
|
|
+ timeCount++;
|
|
|
|
+ osDelay(100);
|
|
|
|
+ if (timeCount>=timeout/100)
|
|
|
|
+ {
|
|
|
|
+ timeCount =0;
|
|
|
|
+ isRecvTimeout = true;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ #ifdef USING_PRINTF
|
|
|
|
+ printf("\nanswer in:");
|
|
|
|
+ for(j=0;j<readLen;j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",*(pRead+j));
|
|
|
|
+ }
|
|
|
|
+ printf("\n");
|
|
|
|
+ #endif
|
|
|
|
+ if (isRecvComplete == true)
|
|
|
|
+ {
|
|
|
|
+ isRecvComplete = false;
|
|
|
|
+ if(*(pRead+0)!=0xEB)
|
|
|
|
+ {
|
|
|
|
+ USARTdrv->Uninitialize();
|
|
|
|
+ osDelay(100);
|
|
|
|
+ USARTdrv->Initialize(USART_callback);
|
|
|
|
+ USARTdrv->PowerControl(ARM_POWER_FULL);
|
|
|
|
+ USARTdrv->Control(ARM_USART_MODE_ASYNCHRONOUS |
|
|
|
|
+ ARM_USART_DATA_BITS_8 |
|
|
|
|
+ ARM_USART_PARITY_NONE |
|
|
|
|
+ ARM_USART_STOP_BITS_1 |
|
|
|
|
+ ARM_USART_FLOW_CONTROL_NONE, 9600);
|
|
|
|
+ #ifdef USING_PRINTF
|
|
|
|
+ printf("\nuart reset in \n");
|
|
|
|
+ #endif
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ return readLen;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ memset(pRead,0x00,readLen);
|
|
|
|
+ isRecvTimeout = false;
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+UINT8 SP_BMS_Update_CheckSUM(UINT8* pSendData,UINT8 len)
|
|
|
|
+{
|
|
|
|
+ UINT8 ret = 0;
|
|
|
|
+ UINT8 i=0;
|
|
|
|
+ for(i=0;i<len;i++)
|
|
|
|
+ {
|
|
|
|
+ ret +=*(pSendData+i);
|
|
|
|
+ }
|
|
|
|
+ return ret&0xFF;
|
|
|
|
+}
|
|
|
|
+//________________________________________________________________________________
|
|
|
|
+updateBMSStatus MS_BMS_Update_Service() //美顺BMS升级服务
|
|
|
|
+{
|
|
|
|
+ #ifdef USING_PRINTF
|
|
|
|
+ UINT8 ii = 0;
|
|
|
|
+ #endif
|
|
|
|
+
|
|
|
|
+ UINT8 errorCount = 0;
|
|
|
|
+ UINT16 currentPackage = 0;
|
|
|
|
+ UINT32 updateDataTotalByteLen = 0;
|
|
|
|
+ UINT16 updateDataPackageCount = 0;
|
|
|
|
+ UINT8 ReadNVMTemp[64];
|
|
|
|
+ UpdateStep_MS_BMS updateStep = MS_UPDATE_STEP_SEND_FIRMWARE_UPDATE_REQUEST_AND_JUMP_TO_BOOTLOADER;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ UINT16 i,j=0;
|
|
|
|
+ UINT8 dataLen = 0;
|
|
|
|
+ UINT8 ret0 = 0;
|
|
|
|
+ updateBMSStatus ret = updateFailed;
|
|
|
|
+
|
|
|
|
+ UINT8 pUpdateMsgSend[80];
|
|
|
|
+ UINT32 updateMsgSendLen = 0;
|
|
|
|
+ UINT32 updateMsgReadLen = 0;
|
|
|
|
+
|
|
|
|
+ BOOL bmsUpdateFlag = TRUE;
|
|
|
|
+ UINT8 bmsAnswerMsg[8];
|
|
|
|
+
|
|
|
|
+ //static UpdateStep step = UPDATE_STEP_CHECK_VERSION;
|
|
|
|
+ UINT8 Cycle_conut = 0;
|
|
|
|
+ UINT16 CRCtemp = 0;
|
|
|
|
+ UINT8 headerLen = 5;
|
|
|
|
+
|
|
|
|
+ UINT8 checkSum = 0x00;
|
|
|
|
+ UINT8 checkSumCal = 0x00;
|
|
|
|
+ UINT8 tempLen = 0x00;
|
|
|
|
+
|
|
|
|
+ BSP_QSPI_Read_Safe(&checkSum,FLASH_BMS_FOTA_START_ADDR,1);
|
|
|
|
+
|
|
|
|
+ memset(ReadNVMTemp, 0, 64);
|
|
|
|
+ BSP_QSPI_Read_Safe(ReadNVMTemp, FLASH_BMS_FOTA_START_ADDR+1, 4); //data
|
|
|
|
+
|
|
|
|
+ updateDataTotalByteLen = ((ReadNVMTemp[0]<<24)&0xFF000000) | ((ReadNVMTemp[1]<<16)&0xFF0000) | ((ReadNVMTemp[2]<<8)&0xFF00) | (ReadNVMTemp[3]&0xFF) ;
|
|
|
|
+ updateDataPackageCount = (updateDataTotalByteLen+(64-1))/64; //进一法 e = (a+(b-1))/b
|
|
|
|
+
|
|
|
|
+ for(i=0; i<((updateDataTotalByteLen+4)+(64-1))/64;i++)
|
|
|
|
+ {
|
|
|
|
+ memset(ReadNVMTemp, 0, 64);
|
|
|
|
+ if((i+1)*64 < (updateDataTotalByteLen+4))
|
|
|
|
+ {
|
|
|
|
+ tempLen = 64;
|
|
|
|
+ BSP_QSPI_Read_Safe(ReadNVMTemp,FLASH_BMS_FOTA_START_ADDR+1+i*64,64);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ tempLen = (updateDataTotalByteLen+4) - i*64;
|
|
|
|
+ BSP_QSPI_Read_Safe(ReadNVMTemp,FLASH_BMS_FOTA_START_ADDR+1+i*64,tempLen);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for(j = 0; j< tempLen; j++)
|
|
|
|
+ {
|
|
|
|
+ checkSumCal = (checkSumCal + ReadNVMTemp[j]) & 0xFF;
|
|
|
|
+ }
|
|
|
|
+ //osDelay(10);
|
|
|
|
+ }
|
|
|
|
+ if(checkSum != checkSumCal)
|
|
|
|
+ {
|
|
|
|
+ #ifdef USING_PRINTF
|
|
|
|
+ printf("checksum error: checksum = %x, checksumCal = %x\n",checkSum,checkSumCal);
|
|
|
|
+ #endif
|
|
|
|
+ ret = updateErrorCheckSumError;
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ #ifdef USING_PRINTF
|
|
|
|
+ printf("checksum OK: checksum = %x, checksumCal = %x\n",checkSum,checkSumCal);
|
|
|
|
+ #endif
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #ifdef USING_PRINTF
|
|
|
|
+ printf(" bmsUpdateFlag = %x, Cycle_conut = %x\n",bmsUpdateFlag,Cycle_conut);
|
|
|
|
+ #endif
|
|
|
|
+ while(bmsUpdateFlag && Cycle_conut<2)
|
|
|
|
+ {
|
|
|
|
+ #ifdef USING_PRINTF
|
|
|
|
+ printf("update ms bms step %d\n:",updateStep);
|
|
|
|
+ #endif
|
|
|
|
+ switch (updateStep)
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ case MS_UPDATE_STEP_SEND_FIRMWARE_UPDATE_REQUEST_AND_JUMP_TO_BOOTLOADER: //0x01
|
|
|
|
+ dataLen = 0x00;
|
|
|
|
+ updateMsgSendLen = 6+dataLen;
|
|
|
|
+ updateMsgReadLen = 8;
|
|
|
|
+
|
|
|
|
+ pUpdateMsgSend[0] = 0x01; //node byte
|
|
|
|
+ pUpdateMsgSend[1] = 0x40; //func byte
|
|
|
|
+ pUpdateMsgSend[2] = updateStep; //cmd byte
|
|
|
|
+ pUpdateMsgSend[3] = dataLen; //data len
|
|
|
|
+ //no data type
|
|
|
|
+ CRCtemp = MS_BMS_Update_CRC16(pUpdateMsgSend, 4);
|
|
|
|
+ pUpdateMsgSend[4] = (CRCtemp>>8)&0xFF; // CRC High
|
|
|
|
+ pUpdateMsgSend[5] = CRCtemp&0xFF; //CRC Low
|
|
|
|
+
|
|
|
|
+ memset((UINT8*)(bmsAnswerMsg) , 0, 8);
|
|
|
|
+ ret0 = MS_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(bmsAnswerMsg), updateMsgReadLen, 500);
|
|
|
|
+ #ifdef USING_PRINTF
|
|
|
|
+ printf("update step 1 answer,updateMsgReadLen = %x:\n",updateMsgReadLen);
|
|
|
|
+
|
|
|
|
+ for(ii=0;ii<updateMsgReadLen;ii++)
|
|
|
|
+ printf("%x ",bmsAnswerMsg[ii]);
|
|
|
|
+
|
|
|
|
+ printf("\nret0 = %d",ret0);
|
|
|
|
+ printf("\n");
|
|
|
|
+ #endif
|
|
|
|
+ if(ret0!=0)
|
|
|
|
+ {
|
|
|
|
+ if(bmsAnswerMsg[0] == 0x01 && bmsAnswerMsg[1] == 0x40) // node and func byte
|
|
|
|
+ {
|
|
|
|
+ if(bmsAnswerMsg[2] == MS_UPDATE_STEP_FIRMWARE_UPDATE_REQUEST_ANSWER && bmsAnswerMsg[3] == 0x02) //answer cmd byte:0x02, answer data len:0x02
|
|
|
|
+ {
|
|
|
|
+ if(bmsAnswerMsg[4] == 0x00) //answer data byte1
|
|
|
|
+ {
|
|
|
|
+ if(bmsAnswerMsg[5] == 0x00) //answer data byte2
|
|
|
|
+ {
|
|
|
|
+ updateStep = MS_UPDATE_STEP_SEND_FIRMWARE_INFO;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if(bmsAnswerMsg[4] == 0x01) //不允许升级
|
|
|
|
+ {
|
|
|
|
+ if(bmsAnswerMsg[5] == 0x01)//电量过低
|
|
|
|
+ {
|
|
|
|
+ updateStep = MS_UPDATE_STEP_ERROR;
|
|
|
|
+ ret = updateErrorBMSPowerLow;
|
|
|
|
+ }
|
|
|
|
+ else if(bmsAnswerMsg[5] == 0x02)//电池存在保护状态不允许升级
|
|
|
|
+ {
|
|
|
|
+ updateStep = MS_UPDATE_STEP_ERROR;
|
|
|
|
+ ret = updateErrorBMSWarningProtect;
|
|
|
|
+ }
|
|
|
|
+ else if(bmsAnswerMsg[5] == 0x03) //不支持升级
|
|
|
|
+ {
|
|
|
|
+ updateStep = MS_UPDATE_STEP_ERROR;
|
|
|
|
+ ret = updateErrorBMSNotSurport;
|
|
|
|
+ }
|
|
|
|
+ else if(bmsAnswerMsg[5] == 0x04) //当前电池处于充放电状态
|
|
|
|
+ {
|
|
|
|
+ updateStep = MS_UPDATE_STEP_ERROR;
|
|
|
|
+ ret = updateErrorBMSWorkState;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(errorCount>10)
|
|
|
|
+ {
|
|
|
|
+ updateStep = MS_UPDATE_STEP_ERROR;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+ osDelay(50);
|
|
|
|
+ printf(" step 1 ret = %d\n",ret);
|
|
|
|
+ break;
|
|
|
|
+ case MS_UPDATE_STEP_SEND_FIRMWARE_INFO: //0x03
|
|
|
|
+ dataLen = 52;
|
|
|
|
+ updateMsgSendLen = 6+dataLen;
|
|
|
|
+ updateMsgReadLen = 7;
|
|
|
|
+ pUpdateMsgSend[0] = 0x01; //node byte
|
|
|
|
+ pUpdateMsgSend[1] = 0x40; //func byte
|
|
|
|
+ pUpdateMsgSend[2] = updateStep; //cmd byte
|
|
|
|
+ pUpdateMsgSend[3] = dataLen; //data len
|
|
|
|
+
|
|
|
|
+ memset(ReadNVMTemp, 0, 64);
|
|
|
|
+ BSP_QSPI_Read_Safe(ReadNVMTemp, FLASH_BMS_FOTA_START_ADDR+headerLen, 16); //data
|
|
|
|
+ MEMCPY(&pUpdateMsgSend[4], ReadNVMTemp, 16); //厂家信息,未开启校验
|
|
|
|
+ MEMCPY(&pUpdateMsgSend[4+16], ReadNVMTemp, 16); //保护板硬件序列号,未开启校验
|
|
|
|
+ pUpdateMsgSend[4+16*2 + 0] = (updateDataTotalByteLen>>24)&0xFF; //固件包大小
|
|
|
|
+ pUpdateMsgSend[4+16*2 + 1] = (updateDataTotalByteLen>>16)&0xFF;
|
|
|
|
+ pUpdateMsgSend[4+16*2 + 2] = (updateDataTotalByteLen>>8)&0xFF;
|
|
|
|
+ pUpdateMsgSend[4+16*2 + 3] = (updateDataTotalByteLen)&0xFF;
|
|
|
|
+ MEMCPY(&pUpdateMsgSend[4+16*2+4], ReadNVMTemp, 16); // 固件包头信息,未开启校验
|
|
|
|
+
|
|
|
|
+ CRCtemp = MS_BMS_Update_CRC16(pUpdateMsgSend, 4+dataLen);
|
|
|
|
+
|
|
|
|
+ pUpdateMsgSend[4+dataLen] = (CRCtemp>>8)&0xFF; // CRC High
|
|
|
|
+ pUpdateMsgSend[5+dataLen] = CRCtemp&0xFF; //CRC Low
|
|
|
|
+
|
|
|
|
+ memset((UINT8*)(bmsAnswerMsg) , 0, 8);
|
|
|
|
+ ret0 = MS_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(bmsAnswerMsg), updateMsgReadLen, 500);
|
|
|
|
+ #ifdef USING_PRINTF
|
|
|
|
+ printf("update step 3 answer:\n");
|
|
|
|
+ for(ii=0;ii<updateMsgReadLen;ii++)
|
|
|
|
+ printf("%x ",bmsAnswerMsg[ii]);
|
|
|
|
+
|
|
|
|
+ printf("\nret0 = %d",ret0);
|
|
|
|
+ printf("\n");
|
|
|
|
+ #endif
|
|
|
|
+ if(ret0!=0)
|
|
|
|
+ {
|
|
|
|
+ if(bmsAnswerMsg[0] == 0x01 && bmsAnswerMsg[1] == 0x40) // node and func byte
|
|
|
|
+ {
|
|
|
|
+ if(bmsAnswerMsg[2] == MS_UPDATE_STEP_FIRMWARE_INFO_CHECK_AND_UPDATE_REQEST_ANSWER && bmsAnswerMsg[3] == 0x01) //answer cmd byte:0x04, answer data len:0x01
|
|
|
|
+ {
|
|
|
|
+ if(bmsAnswerMsg[4] == 0x00) //answer data byte1
|
|
|
|
+ {
|
|
|
|
+ updateStep = MS_UPDATE_STEP_EREASE_APP_FLASH_REQUEST;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+ else if(bmsAnswerMsg[4] == 0x01) //厂家信息错误
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ ret = updateErrorFirmwareInfoError;
|
|
|
|
+ }
|
|
|
|
+ else if(bmsAnswerMsg[4] == 0x02) //硬件序列号不匹配
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ ret = updateErrorFirmwareInfoError;
|
|
|
|
+ }
|
|
|
|
+ else if(bmsAnswerMsg[4] == 0x03) //固件大小超出范围
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ ret = updateErrorFirmwareSizeError;
|
|
|
|
+ }
|
|
|
|
+ else if(bmsAnswerMsg[4] == 0x04) //固件包头信息错误
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ ret = updateErrorFirmwareInfoError;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(errorCount>10)
|
|
|
|
+ {
|
|
|
|
+ updateStep = MS_UPDATE_STEP_ERROR;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+ printf(" step 3 ret = %d\n",ret);
|
|
|
|
+ osDelay(50);
|
|
|
|
+ break;
|
|
|
|
+ case MS_UPDATE_STEP_EREASE_APP_FLASH_REQUEST: //0x05
|
|
|
|
+ dataLen = 0;
|
|
|
|
+ updateMsgSendLen = 6+dataLen;
|
|
|
|
+ updateMsgReadLen = 8;
|
|
|
|
+ pUpdateMsgSend[0] = 0x01; //node byte
|
|
|
|
+ pUpdateMsgSend[1] = 0x40; //func byte
|
|
|
|
+ pUpdateMsgSend[2] = updateStep; //cmd byte
|
|
|
|
+ pUpdateMsgSend[3] = dataLen; //data len
|
|
|
|
+
|
|
|
|
+ CRCtemp = MS_BMS_Update_CRC16(pUpdateMsgSend, 4+dataLen);
|
|
|
|
+
|
|
|
|
+ pUpdateMsgSend[4+dataLen] = (CRCtemp>>8)&0xFF; // CRC High
|
|
|
|
+ pUpdateMsgSend[5+dataLen] = CRCtemp&0xFF; //CRC Low
|
|
|
|
+
|
|
|
|
+ memset((UINT8*)(bmsAnswerMsg) , 0, 8);
|
|
|
|
+ ret0 = MS_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(bmsAnswerMsg), updateMsgReadLen, 500);
|
|
|
|
+ #ifdef USING_PRINTF
|
|
|
|
+ printf("update step 5 answer:\n");
|
|
|
|
+ for(ii=0;ii<updateMsgReadLen;ii++)
|
|
|
|
+ printf("%x ",bmsAnswerMsg[ii]);
|
|
|
|
+
|
|
|
|
+ printf("\nret0 = %d",ret0);
|
|
|
|
+ printf("\n");
|
|
|
|
+ #endif
|
|
|
|
+ if(ret0!=0)
|
|
|
|
+ {
|
|
|
|
+ if(bmsAnswerMsg[0] == 0x01 && bmsAnswerMsg[1] == 0x40) // node and func byte
|
|
|
|
+ {
|
|
|
|
+ if(bmsAnswerMsg[2] == MS_UPDATE_STEP_EREASE_FLASH_ANSWER && bmsAnswerMsg[3] == 0x02) //answer cmd byte:0x06, answer data len:0x02
|
|
|
|
+ {
|
|
|
|
+ if(bmsAnswerMsg[4] == 0x00) //answer data byte1, erease successed
|
|
|
|
+ {
|
|
|
|
+ updateStep = MS_UPDATE_STEP_SEND_UPDATE_DATA; //0x07
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+ else if(bmsAnswerMsg[4] == 0x01) //擦除失败
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ ret = updateErrorAppErease;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(errorCount>10)
|
|
|
|
+ {
|
|
|
|
+ updateStep = MS_UPDATE_STEP_ERROR;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+ osDelay(50);
|
|
|
|
+ break;
|
|
|
|
+ case MS_UPDATE_STEP_SEND_UPDATE_DATA: //0x07
|
|
|
|
+
|
|
|
|
+ updateMsgReadLen = 7;
|
|
|
|
+ pUpdateMsgSend[0] = 0x01; //node byte
|
|
|
|
+ pUpdateMsgSend[1] = 0x40; //func byte
|
|
|
|
+ pUpdateMsgSend[2] = updateStep; //cmd byte
|
|
|
|
+
|
|
|
|
+ for(i = 0; i < updateDataPackageCount ; i++ )
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ memset(ReadNVMTemp, 0, 64);
|
|
|
|
+
|
|
|
|
+ if((i+1)*64 < (updateDataTotalByteLen))
|
|
|
|
+ {
|
|
|
|
+ tempLen = 64;
|
|
|
|
+ BSP_QSPI_Read_Safe(ReadNVMTemp,FLASH_BMS_FOTA_START_ADDR+headerLen+i*64,64);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ tempLen = (updateDataTotalByteLen+4) - i*64;
|
|
|
|
+ BSP_QSPI_Read_Safe(ReadNVMTemp,FLASH_BMS_FOTA_START_ADDR+headerLen+i*64,tempLen);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ CRCtemp = MS_BMS_Update_CRC16(ReadNVMTemp, tempLen);
|
|
|
|
+
|
|
|
|
+ dataLen = tempLen+6; //data len =count(2+2 byte) + crc(2byte) + update data len
|
|
|
|
+ updateMsgSendLen = 6+dataLen; // updateMsgSendLen = data len + header len(6byte)
|
|
|
|
+
|
|
|
|
+ pUpdateMsgSend[3] = dataLen; //data len
|
|
|
|
+
|
|
|
|
+ pUpdateMsgSend[4] = ((i+1)>>8)&0xFF; //当前包序号,大端模式
|
|
|
|
+ pUpdateMsgSend[5] = (i+1)&0xFF;
|
|
|
|
+
|
|
|
|
+ pUpdateMsgSend[6] = (updateDataPackageCount>>8)&0xFF;
|
|
|
|
+ pUpdateMsgSend[7] = updateDataPackageCount&0xFF;
|
|
|
|
+ pUpdateMsgSend[8] = (CRCtemp>>8)&0xFF; // data CRC High
|
|
|
|
+ pUpdateMsgSend[9] = CRCtemp&0xFF; //data CRC Low
|
|
|
|
+
|
|
|
|
+ MEMCPY(&pUpdateMsgSend[4+6], ReadNVMTemp, 64); //升级数据,64字节
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ CRCtemp = MS_BMS_Update_CRC16(pUpdateMsgSend, 4+dataLen);
|
|
|
|
+
|
|
|
|
+ pUpdateMsgSend[4+dataLen] = (CRCtemp>>8)&0xFF; // CRC High
|
|
|
|
+ pUpdateMsgSend[5+dataLen] = CRCtemp&0xFF; //CRC Low
|
|
|
|
+
|
|
|
|
+ memset((UINT8*)(bmsAnswerMsg) , 0, 8);
|
|
|
|
+ ret0 = MS_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(bmsAnswerMsg), updateMsgReadLen, 500);
|
|
|
|
+ #ifdef USING_PRINTF
|
|
|
|
+ printf("update step 7 answer:\n");
|
|
|
|
+ for(ii=0;ii<updateMsgReadLen;ii++)
|
|
|
|
+ printf("%x ",bmsAnswerMsg[ii]);
|
|
|
|
+
|
|
|
|
+ printf("\nret0 = %d",ret0);
|
|
|
|
+ printf("\n");
|
|
|
|
+ #endif
|
|
|
|
+ if(ret0!=0)
|
|
|
|
+ {
|
|
|
|
+ if(bmsAnswerMsg[0] == 0x01 && bmsAnswerMsg[1] == 0x40) // node and func byte
|
|
|
|
+ {
|
|
|
|
+ if(bmsAnswerMsg[2] == MS_UPDATE_STEP_UPDATE_DATA_WRITE_ANSWER && bmsAnswerMsg[3] == 0x01) //answer cmd byte:0x04, answer data len:0x01
|
|
|
|
+ {
|
|
|
|
+ if(bmsAnswerMsg[4] == 0x00) //answer data byte1,接收并操作成功
|
|
|
|
+ {
|
|
|
|
+ updateStep = MS_UPDATE_STEP_EREASE_APP_FLASH_REQUEST;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+ else if(bmsAnswerMsg[4] == 0x01) //固件块校验失败
|
|
|
|
+ {
|
|
|
|
+ errorCount=10;
|
|
|
|
+ ret = updateErrorPackageCRC;
|
|
|
|
+ }
|
|
|
|
+ else if(bmsAnswerMsg[4] == 0x02) //烧写失败
|
|
|
|
+ {
|
|
|
|
+ errorCount=10;
|
|
|
|
+ ret = updateErrorPackageWrite;
|
|
|
|
+ }
|
|
|
|
+ else if(bmsAnswerMsg[4] == 0x03) //固件块编号异常
|
|
|
|
+ {
|
|
|
|
+ errorCount=10;
|
|
|
|
+ ret = updateErrorPackageNo;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount=10;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount=10;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount=10;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount=10;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(errorCount>=10)
|
|
|
|
+ {
|
|
|
|
+ updateStep = MS_UPDATE_STEP_ERROR;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ i--;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ osDelay(50);
|
|
|
|
+ }
|
|
|
|
+ if(i == updateDataPackageCount)
|
|
|
|
+ {
|
|
|
|
+ updateStep = MS_UPDATE_STEP_SEND_UPDATE_DATA_END_AND_JUMP_TO_APP;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case MS_UPDATE_STEP_SEND_UPDATE_DATA_END_AND_JUMP_TO_APP: //0x09
|
|
|
|
+ dataLen = 0x00;
|
|
|
|
+ updateMsgSendLen = 6+dataLen;
|
|
|
|
+ updateMsgReadLen = 7;
|
|
|
|
+
|
|
|
|
+ pUpdateMsgSend[0] = 0x01; //node byte
|
|
|
|
+ pUpdateMsgSend[1] = 0x40; //func byte
|
|
|
|
+ pUpdateMsgSend[2] = updateStep; //cmd byte
|
|
|
|
+ pUpdateMsgSend[3] = dataLen; //data len
|
|
|
|
+ //no data type
|
|
|
|
+ CRCtemp = MS_BMS_Update_CRC16(pUpdateMsgSend, 4);
|
|
|
|
+ pUpdateMsgSend[4] = (CRCtemp>>8)&0xFF; // CRC High
|
|
|
|
+ pUpdateMsgSend[5] = CRCtemp&0xFF; //CRC Low
|
|
|
|
+
|
|
|
|
+ memset((UINT8*)(bmsAnswerMsg) , 0, 8);
|
|
|
|
+ ret0 = MS_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(bmsAnswerMsg), updateMsgReadLen, 500);
|
|
|
|
+ #ifdef USING_PRINTF
|
|
|
|
+ printf("update step 9 answer:\n");
|
|
|
|
+ for(ii=0;ii<updateMsgReadLen;ii++)
|
|
|
|
+ printf("%x ",bmsAnswerMsg[ii]);
|
|
|
|
+
|
|
|
|
+ printf("\nret0 = %d",ret0);
|
|
|
|
+ printf("\n");
|
|
|
|
+ #endif
|
|
|
|
+ if(ret0!=0)
|
|
|
|
+ {
|
|
|
|
+ if(bmsAnswerMsg[0] == 0x01 && bmsAnswerMsg[1] == 0x40) // node and func byte
|
|
|
|
+ {
|
|
|
|
+ if(bmsAnswerMsg[2] == MS_UPDATE_STEP_JUMP_TO_APP_ANSWER && bmsAnswerMsg[3] == 0x01) //answer cmd byte:0x0A, answer data len:0x01
|
|
|
|
+ {
|
|
|
|
+ if(bmsAnswerMsg[4] == 0x00) //answer data byte1, update succeed
|
|
|
|
+ {
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ updateStep = MS_UPDATE_STEP_READ_CURRENT_RUNNING_MODE; //0x0B
|
|
|
|
+ }
|
|
|
|
+ else if(bmsAnswerMsg[4] == 0x01) //升级失败
|
|
|
|
+ {
|
|
|
|
+ errorCount = 10;
|
|
|
|
+ ret = updateFailed;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(errorCount>=10)
|
|
|
|
+ {
|
|
|
|
+ updateStep = MS_UPDATE_STEP_ERROR;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+ osDelay(50);
|
|
|
|
+ break;
|
|
|
|
+ case MS_UPDATE_STEP_READ_CURRENT_RUNNING_MODE: //0x0B
|
|
|
|
+ dataLen = 0x00;
|
|
|
|
+ updateMsgSendLen = 6+dataLen;
|
|
|
|
+ updateMsgReadLen = 8;
|
|
|
|
+
|
|
|
|
+ pUpdateMsgSend[0] = 0x01; //node byte
|
|
|
|
+ pUpdateMsgSend[1] = 0x40; //func byte
|
|
|
|
+ pUpdateMsgSend[2] = updateStep; //cmd byte
|
|
|
|
+ pUpdateMsgSend[3] = dataLen; //data len
|
|
|
|
+ //no data type
|
|
|
|
+ CRCtemp = MS_BMS_Update_CRC16(pUpdateMsgSend, 4);
|
|
|
|
+ pUpdateMsgSend[4] = (CRCtemp>>8)&0xFF; // CRC High
|
|
|
|
+ pUpdateMsgSend[5] = CRCtemp&0xFF; //CRC Low
|
|
|
|
+
|
|
|
|
+ memset((UINT8*)(bmsAnswerMsg) , 0, 8);
|
|
|
|
+ ret0 = MS_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(bmsAnswerMsg), updateMsgReadLen, 500);
|
|
|
|
+ #ifdef USING_PRINTF
|
|
|
|
+ printf("update step A answer:\n");
|
|
|
|
+ for(ii=0;ii<updateMsgReadLen;ii++)
|
|
|
|
+ printf("%x ",bmsAnswerMsg[ii]);
|
|
|
|
+
|
|
|
|
+ printf("\nret0 = %d",ret0);
|
|
|
|
+ printf("\n");
|
|
|
|
+ #endif
|
|
|
|
+ if(ret0!=0)
|
|
|
|
+ {
|
|
|
|
+ if(bmsAnswerMsg[0] == 0x01 && bmsAnswerMsg[1] == 0x40) // node and func byte
|
|
|
|
+ {
|
|
|
|
+ if(bmsAnswerMsg[2] == MS_UPDATE_STEP_CURRENT_RUNNING_MODE_ANSWER && bmsAnswerMsg[3] == 0x02) //answer cmd byte:0x0C, answer data len:0x02
|
|
|
|
+ {
|
|
|
|
+ if(bmsAnswerMsg[4] == 0x01) //answer data byte1, update succeed, app is running
|
|
|
|
+ {
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ updateStep = MS_UPDATE_STEP_END;
|
|
|
|
+ }
|
|
|
|
+ else if(bmsAnswerMsg[4] == 0x00) //update failed , boot is running,error
|
|
|
|
+ {
|
|
|
|
+ errorCount = 10;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errorCount++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(errorCount>=3)
|
|
|
|
+ {
|
|
|
|
+ updateStep = MS_UPDATE_STEP_ERROR;
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ }
|
|
|
|
+ osDelay(50);
|
|
|
|
+ break;
|
|
|
|
+ case MS_UPDATE_STEP_END: //0x0D
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ bmsUpdateFlag = FALSE;
|
|
|
|
+ ret = updateOK;
|
|
|
|
+ break;
|
|
|
|
+ case MS_UPDATE_STEP_ERROR: //0x0E
|
|
|
|
+ errorCount = 0;
|
|
|
|
+ bmsUpdateFlag = true;
|
|
|
|
+ Cycle_conut++;
|
|
|
|
+ if(Cycle_conut>2)
|
|
|
|
+ {
|
|
|
|
+ ret = updateErrorTimeout;
|
|
|
|
+ bmsUpdateFlag = FALSE;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ bmsUpdateFlag = FALSE;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ #ifdef USING_PRINTF
|
|
|
|
+ printf("last ret = %x\n",ret);
|
|
|
|
+ #endif
|
|
|
|
+ return ret;
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+UINT8 MS_BMS_Update_Query(UINT8* pSend,UINT32 sendLen, UINT8* pRead, UINT32 readLen, UINT32 timeout)
|
|
|
|
+{
|
|
|
|
+
|
|
|
|
+ UINT8 timeCount = 0;
|
|
|
|
+ UINT8 j=0;
|
|
|
|
+ USARTdrv->Send(pSend,sendLen);
|
|
|
|
+ #ifdef USING_PRINTF
|
|
|
|
+ printf("query in:");
|
|
|
|
+ for(j=0;j<sendLen;j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",*(pSend+j));
|
|
|
|
+ }
|
|
|
|
+ printf("\n");
|
|
|
|
+ #endif
|
|
|
|
+ if(readLen>0)
|
|
|
|
+ {
|
|
|
|
+ USARTdrv->Receive(pRead,readLen);
|
|
|
|
+ while((isRecvTimeout == false) && (isRecvComplete == false))
|
|
|
|
+ {
|
|
|
|
+ timeCount++;
|
|
|
|
+ osDelay(100);
|
|
|
|
+ if (timeCount>=timeout/100)
|
|
|
|
+ {
|
|
|
|
+ timeCount =0;
|
|
|
|
+ isRecvTimeout = true;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ #ifdef USING_PRINTF
|
|
|
|
+ printf("\nanswer in:");
|
|
|
|
+ for(j=0;j<readLen;j++)
|
|
|
|
+ {
|
|
|
|
+ printf("%x ",*(pRead+j));
|
|
|
|
+ }
|
|
|
|
+ printf("\n");
|
|
|
|
+ #endif
|
|
|
|
+ if (isRecvComplete == true)
|
|
|
|
+ {
|
|
|
|
+ isRecvComplete = false;
|
|
|
|
+ if(*(pRead+0)!=0x01)
|
|
|
|
+ {
|
|
|
|
+ USARTdrv->Uninitialize();
|
|
|
|
+ osDelay(100);
|
|
|
|
+ USARTdrv->Initialize(USART_callback);
|
|
|
|
+ USARTdrv->PowerControl(ARM_POWER_FULL);
|
|
|
|
+ USARTdrv->Control(ARM_USART_MODE_ASYNCHRONOUS |
|
|
|
|
+ ARM_USART_DATA_BITS_8 |
|
|
|
|
+ ARM_USART_PARITY_NONE |
|
|
|
|
+ ARM_USART_STOP_BITS_1 |
|
|
|
|
+ ARM_USART_FLOW_CONTROL_NONE, 9600);
|
|
|
|
+ #ifdef USING_PRINTF
|
|
|
|
+ printf("\nuart reset in \n");
|
|
|
|
+ #endif
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ return readLen;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ memset(pRead,0x00,readLen);
|
|
|
|
+ isRecvTimeout = false;
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ return 1;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+static void __invert_uint8(UINT8* dBuf, UINT8* srcBuf)
|
|
|
|
+{
|
|
|
|
+ int i;
|
|
|
|
+ UINT8 tmp[4];
|
|
|
|
+ tmp[0] = 0;
|
|
|
|
+ for (i = 0;i < 8;i++)
|
|
|
|
+ {
|
|
|
|
+ if(srcBuf[0] & (1 << i))
|
|
|
|
+ {
|
|
|
|
+ tmp[0] |= 1<<(7-i);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ dBuf[0] = tmp[0];
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+static void __invert_uint16(UINT16* dBuf, UINT16* srcBuf)
|
|
|
|
+{
|
|
|
|
+ int i;
|
|
|
|
+ UINT16 tmp[4];
|
|
|
|
+ tmp[0] = 0;
|
|
|
|
+ for (i = 0;i < 16;i++)
|
|
|
|
+ {
|
|
|
|
+ if(srcBuf[0] & (1 << i))
|
|
|
|
+ {
|
|
|
|
+ tmp[0] |= 1 << (15 - i);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ dBuf[0] = tmp[0];
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+UINT16 MS_BMS_Update_CRC16(UINT8* pSendData,UINT16 len)
|
|
|
|
+{
|
|
|
|
+
|
|
|
|
+ UINT16 wCRCin = 0xFFFF;
|
|
|
|
+ UINT16 wCPoly = 0x8005;
|
|
|
|
+ UINT8 wChar = 0;
|
|
|
|
+ UINT16 crc_rslt = 0;
|
|
|
|
+ int i;
|
|
|
|
+ while (len--)
|
|
|
|
+ {
|
|
|
|
+ wChar = *(pSendData++);
|
|
|
|
+ __invert_uint8(&wChar, &wChar);
|
|
|
|
+ wCRCin ^= (wChar << 8);
|
|
|
|
+ for (i = 0;i < 8;i++)
|
|
|
|
+ {
|
|
|
|
+ if(wCRCin & 0x8000)
|
|
|
|
+ {
|
|
|
|
+ wCRCin = (wCRCin << 1) ^ wCPoly;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ wCRCin = wCRCin << 1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ __invert_uint16(&wCRCin, &wCRCin);
|
|
|
|
+ crc_rslt = ((wCRCin << 8) & 0xFF00) | ((wCRCin >> 8) & 0x00FF);
|
|
|
|
+ return (crc_rslt);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+UINT8 BmsErrorDecode(UINT32 battWarningState)
|
|
|
|
+{
|
|
|
|
+ UINT16 ErrorNumTemp;
|
|
|
|
+ UINT8 ret;
|
|
|
|
+ if(battWarningState==0)
|
|
|
|
+ {
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if(osOK==osMutexAcquire(Error_Mutex, 100))
|
|
|
|
+ {
|
|
|
|
+ ret = ((battWarningState) & 0x01) == 1 ;
|
|
|
|
+ if (ret)
|
|
|
|
+ {
|
|
|
|
+ ErrorNumTemp = 7;
|
|
|
|
+ PutErrorNum((UINT16 *)ErrorNum,sizeof(ErrorNum),ErrorNumTemp);
|
|
|
|
+ //str += "ERROR:存在电芯过放告警故障!!\n";单体电压过低
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ((battWarningState >> 1) & 0x01) == 1 ;
|
|
|
|
+ if (ret)
|
|
|
|
+ {
|
|
|
|
+ ErrorNumTemp = 10;
|
|
|
|
+ PutErrorNum((UINT16 *)ErrorNum,sizeof(ErrorNum),ErrorNumTemp);
|
|
|
|
+ //str += "ERROR:存在总电压过放告警故障!!\n";总电压过低
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ((battWarningState >> 2) & 0x01) == 1 ;
|
|
|
|
+ if (ret)
|
|
|
|
+ {
|
|
|
|
+ ErrorNumTemp = 8;
|
|
|
|
+ PutErrorNum((UINT16 *)ErrorNum,sizeof(ErrorNum),ErrorNumTemp);
|
|
|
|
+ //str += "ERROR:存在电芯过压告警故障!!\n";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ((battWarningState >> 3) & 0x01) == 1 ;
|
|
|
|
+ if (ret)
|
|
|
|
+ {
|
|
|
|
+ ErrorNumTemp = 11;
|
|
|
|
+ PutErrorNum((UINT16 *)ErrorNum,sizeof(ErrorNum),ErrorNumTemp);
|
|
|
|
+ //str += "ERROR:存在总电压过压告警故障!!\n";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ((battWarningState >> 4) & 0x01) == 1 ;
|
|
|
|
+ if (ret)
|
|
|
|
+ {
|
|
|
|
+ ErrorNumTemp = 12;
|
|
|
|
+ PutErrorNum((UINT16 *)ErrorNum,sizeof(ErrorNum),ErrorNumTemp);
|
|
|
|
+ //str += "ERROR:存在放电过流告警故障!!\n";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ((battWarningState >> 5) & 0x01) == 1 ;
|
|
|
|
+ if (ret)
|
|
|
|
+ {
|
|
|
|
+ ErrorNumTemp = 13;
|
|
|
|
+ PutErrorNum((UINT16 *)ErrorNum,sizeof(ErrorNum),ErrorNumTemp);
|
|
|
|
+ //str += "ERROR:存在充电过流告警故障!!\n";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ((battWarningState >> 6) & 0x01) == 1 ;
|
|
|
|
+ if (ret)
|
|
|
|
+ {
|
|
|
|
+ ErrorNumTemp = 2;
|
|
|
|
+ PutErrorNum((UINT16 *)ErrorNum,sizeof(ErrorNum),ErrorNumTemp);
|
|
|
|
+ //str += "ERROR:存在放电过温告警故障!!\n";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ((battWarningState >> 7) & 0x01) == 1 ;
|
|
|
|
+ if (ret)
|
|
|
|
+ {
|
|
|
|
+ ErrorNumTemp = 2;
|
|
|
|
+ PutErrorNum((UINT16 *)ErrorNum,sizeof(ErrorNum),ErrorNumTemp);
|
|
|
|
+ //str += "ERROR:存在充电过温告警故障!!\n";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ((battWarningState >> 8) & 0x01) == 1 ;
|
|
|
|
+ if (ret)
|
|
|
|
+ {
|
|
|
|
+ //str += "ERROR:存在环境高温告警故障!!\n";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ((battWarningState >> 9) & 0x01) == 1 ;
|
|
|
|
+ if (ret)
|
|
|
|
+ {
|
|
|
|
+ //str += "ERROR:存在环境低温告警故障!!\n";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ((battWarningState >> 10) & 0x01) == 1 ;
|
|
|
|
+ if (ret)
|
|
|
|
+ {
|
|
|
|
+ ErrorNumTemp = 27;
|
|
|
|
+ PutErrorNum((UINT16 *)ErrorNum,sizeof(ErrorNum),ErrorNumTemp);
|
|
|
|
+ //str += "ERROR:存在battSOC低告警故障!!\n";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ((battWarningState >> 11) & 0x01) == 1 ;
|
|
|
|
+ if (ret)
|
|
|
|
+ {
|
|
|
|
+ ErrorNumTemp = 3;
|
|
|
|
+ PutErrorNum((UINT16 *)ErrorNum,sizeof(ErrorNum),ErrorNumTemp);
|
|
|
|
+ //str += "ERROR:存在MOS高温告警故障!!\n";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ((battWarningState >> 16) & 0x01) == 1;
|
|
|
|
+ if (ret)
|
|
|
|
+ {
|
|
|
|
+ ErrorNumTemp = 18;
|
|
|
|
+ PutErrorNum((UINT16 *)ErrorNum,sizeof(ErrorNum),ErrorNumTemp);
|
|
|
|
+ //str += "ERROR:存在温度采集失效/传感器故障!!\n";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ((battWarningState >> 17) & 0x01) == 1;
|
|
|
|
+ if (ret)
|
|
|
|
+ {
|
|
|
|
+ ErrorNumTemp = 19;
|
|
|
|
+ PutErrorNum((UINT16 *)ErrorNum,sizeof(ErrorNum),ErrorNumTemp);
|
|
|
|
+ //str += "ERROR:存在电压采集失效/断线故障!!\n";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ((battWarningState >> 18) & 0x01) == 1;
|
|
|
|
+ if (ret)
|
|
|
|
+ {
|
|
|
|
+ ErrorNumTemp = 17;
|
|
|
|
+ PutErrorNum((UINT16 *)ErrorNum,sizeof(ErrorNum),ErrorNumTemp);
|
|
|
|
+ //str += "ERROR:存在放电MOS失效故障!!\n";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ((battWarningState >> 19) & 0x01) == 1;
|
|
|
|
+ if (ret)
|
|
|
|
+ {
|
|
|
|
+ ErrorNumTemp = 16;
|
|
|
|
+ PutErrorNum((UINT16 *)ErrorNum,sizeof(ErrorNum),ErrorNumTemp);
|
|
|
|
+ //str += "ERROR:存在充电MOS失效故障!!\n";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ((battWarningState >> 20) & 0x01) == 1;
|
|
|
|
+ if (ret)
|
|
|
|
+ {
|
|
|
|
+ ErrorNumTemp = 22;
|
|
|
|
+ PutErrorNum((UINT16 *)ErrorNum,sizeof(ErrorNum),ErrorNumTemp);
|
|
|
|
+ //str += "ERROR:存在电芯不均衡告警!!\n";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ((battWarningState >> 22) & 0x01) == 1;
|
|
|
|
+ if (ret)
|
|
|
|
+ {
|
|
|
|
+ ErrorNumTemp = 1;
|
|
|
|
+ PutErrorNum((UINT16 *)ErrorNum,sizeof(ErrorNum),ErrorNumTemp);
|
|
|
|
+ //str += "ERROR:存在放电低温告警故障!!\n";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = ((battWarningState >> 23) & 0x01) == 1 ;
|
|
|
|
+ if (ret)
|
|
|
|
+ {
|
|
|
|
+ ErrorNumTemp = 1;
|
|
|
|
+ PutErrorNum((UINT16 *)ErrorNum,sizeof(ErrorNum),ErrorNumTemp);
|
|
|
|
+ //str += "ERROR:存在充电低温告警故障!!\n";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ #ifdef USING_PRINTF
|
|
|
|
+ printf("get Muxtex error\n");
|
|
|
|
+ #endif
|
|
|
|
+ }
|
|
|
|
+ osMutexRelease(Error_Mutex);
|
|
|
|
+ }
|
|
|
|
+ return 1;
|
|
|
|
+}
|