/**************************************************************************** * * 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 #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 #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; extern UINT8 UDSSwitch; //全局变量输出区 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 relayControlFunc(float DutyRatio,UINT8 BuzzerPeriod); 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(1,sizeof(Uart_Write_Data_Type), NULL); } //上电起始控制区域 UINT8 ret = 0x00,Ringtimes = 0; UINT8 HeatSwitch = 0; 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) { Ringtimes = 0; PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_SLEEP); break; } 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 && uartReadSuccessFlag==TRUE) { #ifdef USING_PRINTF printf("[%d]UartWriteCmdHandle :%x-%X%X\n",__LINE__,UartWriteData.WriteCmd,UartWriteData.Data[0],UartWriteData.Data[1]); #endif Ringtimes = 0; PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_WRITE); break; } else { PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_READ); break; } } if(maxCellVol>4400&&maxCellVol<6000)//继电器测试 { AppDataInfo.RelayControl=TRUE; } else if(maxCellVol<4000) { AppDataInfo.RelayControl=FALSE; } 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(); } if(AppNVMData.isBattLocked==FALSE && ret==0x01) { relayControlFunc(0.6,5);//表示1s响2次,占比80% Ringtimes++; if(Ringtimes>=15) { relayControl(FALSE); ret = 0; Ringtimes = 0; } } else if (AppNVMData.isBattLocked==TRUE && ret==0x01) { relayControlFunc(0.6,5);//表示1s响2次,占比80% Ringtimes++; if(Ringtimes>=10) { relayControl(FALSE); ret = 0; Ringtimes = 0; } } else if(UDSSwitch==1 && Ringtimes<=50) { relayControlFunc(0.6,5);//表示1s响2次,占比80% Ringtimes++; } else if(BuzzerControl==TRUE) { relayControlFunc(0.6,5);//表示1s响2次,占比80% } if(Ringtimes>=50) { relayControl(FALSE); } } currentTimerCount = Timer_count; if(BMS_Fota_update_flag) { if(WorkFlag==0x00) { PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_UPDATE); break; } } if(battWorkState ==0x00 && AppNVMData.isBattLocked==TRUE && ((UartReadMsg.data[(0x1B+BATT_CELL_VOL_NUM+BATT_TEMP_NUM+BATT_OTHER_TEMP_NUM)*2+1])&0x03)!=0x02)//try to lock lock the discharge { #ifdef USING_PRINTF printf("[%d]try to lock:%X-%X\n",__LINE__,AppNVMData.isBattLocked,(UartReadMsg.data[(0x1B+BATT_CELL_VOL_NUM+BATT_TEMP_NUM+BATT_OTHER_TEMP_NUM)*2+1])&0x03); #endif UartWriteData.WriteCmd = 0x01; UartWriteData.Data[0] = 0x00|(UartReadMsg.data[(0x1B+BATT_CELL_VOL_NUM+BATT_TEMP_NUM+BATT_OTHER_TEMP_NUM)*2]); UartWriteData.Data[1] = 0x02; osMessageQueuePut(UartWriteCmdHandle,&UartWriteData,0,0); } else if (battWorkState ==0x00 && AppNVMData.isBattLocked==FALSE && ((UartReadMsg.data[(0x1B+BATT_CELL_VOL_NUM+BATT_TEMP_NUM+BATT_OTHER_TEMP_NUM)*2+1])&0x03)!=0x03) // try to unlock { #ifdef USING_PRINTF printf("[%d]try to unlock:%X-%X\n",__LINE__,AppNVMData.isBattLocked,(UartReadMsg.data[(0x1B+BATT_CELL_VOL_NUM+BATT_TEMP_NUM+BATT_OTHER_TEMP_NUM)*2+1])&0x03); #endif UartWriteData.WriteCmd = 0x01; UartWriteData.Data[0] = 0x00|(UartReadMsg.data[(0x1B+BATT_CELL_VOL_NUM+BATT_TEMP_NUM+BATT_OTHER_TEMP_NUM)*2]); UartWriteData.Data[1] = 0x03; osMessageQueuePut(UartWriteCmdHandle,&UartWriteData,0,0); } if(AppDataInfo.RelayControl==TRUE && ((UartReadMsg.data[(0x1B+BATT_CELL_VOL_NUM+BATT_TEMP_NUM+BATT_OTHER_TEMP_NUM)*2])&0x80)==0x00)//继电器断开 { UartWriteData.WriteCmd = 0x03; UartWriteData.Data[0] = 0x80; UartWriteData.Data[1] = 0x00|(UartReadMsg.data[(0x1B+BATT_CELL_VOL_NUM+BATT_TEMP_NUM+BATT_OTHER_TEMP_NUM)*2+1]); osMessageQueuePut(UartWriteCmdHandle,&UartWriteData,0,0); } else if(AppDataInfo.RelayControl==FALSE && ((UartReadMsg.data[(0x1B+BATT_CELL_VOL_NUM+BATT_TEMP_NUM+BATT_OTHER_TEMP_NUM)*2])&0x80)==0x80)//继电器闭合 { UartWriteData.WriteCmd = 0x03; UartWriteData.Data[0] = 0x00; UartWriteData.Data[1] = 0x00|(UartReadMsg.data[(0x1B+BATT_CELL_VOL_NUM+BATT_TEMP_NUM+BATT_OTHER_TEMP_NUM)*2+1]); osMessageQueuePut(UartWriteCmdHandle,&UartWriteData,0,0); } if(BattHeaterSwitch(&HeatSwitch)==TRUE) { UartWriteData.WriteCmd = 0x02; UartWriteData.Data[0] = 0x00; UartWriteData.Data[1] = HeatSwitch&0xFF; osMessageQueuePut(UartWriteCmdHandle,&UartWriteData,0,0); } break; } case PROCESS_UART_STATE_READ: { UINT16 CRC_chk_buffer; Reg_Num = 0x21+BATT_CELL_VOL_NUM+BATT_TEMP_NUM + BATT_OTHER_TEMP_NUM;//按照协议里面的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("[%d]lock:%X,permit:%X,Mos:%x\n",__LINE__,AppNVMData.isBattLocked,(UartReadMsg.data[(0x1B+BATT_CELL_VOL_NUM+BATT_TEMP_NUM+BATT_OTHER_TEMP_NUM)*2+1])&0x03,((UartReadMsg.data[(0x09+BATT_CELL_VOL_NUM+BATT_OTHER_TEMP_NUM)*2+1])>>1)&0x03); #endif break; } case PROCESS_UART_STATE_WRITE: { ret = Uart_WriteCmd_func(UartWriteData); osDelay(500); PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_READ); 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;i0x8000)// 数据为负 { //求补码,结果为负 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); chargerConnectState = (dataPtr[(0x03+BATT_CELL_VOL_NUM)*2+1]>>2)&0x01;//充电器连接状态,0表示未连接,1表示已连接 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); #ifdef USING_PRINTF1 printf("[%d]battMOSSwitchState :%x\n",__LINE__,battMOSSwitchState); #endif 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]); BattRemainCap = (dataPtr[(0x12+BATT_CELL_VOL_NUM+TEMP_NUM)*2])<<24|(dataPtr[(0x12+BATT_CELL_VOL_NUM+TEMP_NUM)*2+1])<<16|(dataPtr[(0x13+BATT_CELL_VOL_NUM+TEMP_NUM)*2])<<8|(dataPtr[(0x13+BATT_CELL_VOL_NUM+TEMP_NUM)*2+1]); battProtectState = (dataPtr[(0x03+BATT_CELL_VOL_NUM)*2+0]<<24) | (dataPtr[(0x04+BATT_CELL_VOL_NUM)*2+0] << 16) |(dataPtr[(0x04+BATT_CELL_VOL_NUM)*2+1]<<8) | (dataPtr[(0x05+BATT_CELL_VOL_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]; RelayControlState = (dataPtr[(0x1B+BATT_CELL_VOL_NUM+TEMP_NUM)*2])&0x80; battHeatEnableState = dataPtr[(0x1C+BATT_CELL_VOL_NUM+TEMP_NUM)*2+1]&0x01; //SOC问题紧急修复 UINT8 SOC1 = 0; static UINT8 SOC_counter=0; SOC1 = (battPackVol*45-27000)/100; if((battSOC - SOC1>10)&&(battPackVol>500)&&(battPackVol<900)) { SOC_counter++; } else { SOC_counter = 0; } if(SOC_counter>=10) { if(SOC_counter>=200) { SOC_counter==10; } battSOC = SOC1; if(osOK==osMutexAcquire(Error_Mutex, 100)) { UINT8 ErrorNumTemp = 238; PutErrorNum((UINT16 *)ErrorNum,sizeof(ErrorNum),ErrorNumTemp); } osMutexRelease(Error_Mutex); } maxCellTemp = 0x00; minCellTemp = 0xFF; for(i=0;i>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]; #ifdef USING_PRINTF printf("\nUart_WriteCmd_func: %x ",UartWriteData.WriteCmd); #endif 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; } case 0x03://是否继电器控制 { 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; } default: { UartWriteData.WriteCmd = 0x00; return 0; break; } } USARTdrv->Send((UINT8 *)&Uart_Write_Msg,sizeof(Uart_Write_Msg)); #ifdef USING_PRINTF printf("Uart_Send_buffer: "); for(int i=0;iReceive(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_PRINTF 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;jUninitialize(); 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 = battHeatEnableState & 0x01; if(currentSwitchState==0) //当前状态为关闭,判断是否应该开启 { if((chargerConnectState == 1 && minCellTemp<5+40 && minCellTemp>=-29+40 && maxCellTemp<25+40)||(chargerConnectState==0 && minCellTemp<5+40 && minCellTemp>=-29+40 && battSOC>=10 && (((battProtectState>> 21)&0x01) == 0)))//温度偏移为40 { *heaterSwitch = 1; isNeedtoSwitch = true; } } else //当前状态为开启,判断是否应该关闭 { if((minCellTemp>=10+40 || maxCellTemp>=30+40)||(chargerConnectState == 0 && minCellTemp<5+40 && minCellTemp>=-29+40 && battSOC<5)) { *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) && lightTimer10&&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) && lightTimer25&&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) && lightTimer50&&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) && lightTimer75&&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) && lightTimer97&&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(battWorkState == 0x02) //充电模式下,如果只有“SOC低故障”,那么就不显示故障灯 zhengchao20210713 add { if((((battWarningState >> 10) & 0x01) == 0x01) && ((battWarningState & 0xFFFFFBFF) == 0x00)) return; } if(battWarningState != 0 ) { if(errorLightTimer<(UINT8)(errorLEDFlashPeriod*errorDutyRatio)) { FaultDisplay(LED_TURN_ON); } else if(errorLightTimer>=(UINT8)(errorLEDFlashPeriod*errorDutyRatio) && errorLightTimer=(UINT8)(warningLEDFlashPeriod*warningDutyRatio) && warningLightTimer=(UINT8)(errorLEDFlashPeriod*errorDutyRatio) && errorLightTimer=(UINT8)(BuzzerPeriod*DutyRatio) && BuzzerTimer0) { 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;j10) { 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;j10) { 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;j10) { updateStep = UPDATE_STEP_RESET; errorCount = 0; } #ifdef USING_PRINTF1 //printf("update step:%d\n",updateStep); printf("query:"); for(j=0;j10) { updateStep = UPDATE_STEP_RESET; errorCount = 0; } #ifdef USING_PRINTF1 //printf("update step:%d\n",updateStep); printf("query:"); for(j=0;j>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;j10) { updateStep = UPDATE_STEP_RESET; errorCount = 0; } #ifdef USING_PRINTF1 //printf("update step:%d\n",updateStep); printf("query:"); for(j=0;j>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;j10) { updateStep = UPDATE_STEP_RESET; errorCount = 0; } #ifdef USING_PRINTF1 //printf("update step:%d\n",updateStep); printf("query:"); for(j=0;j=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;j0) { 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;jUninitialize(); 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>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;ii10) { 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;ii10) { 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;ii10) { 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=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=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=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;j0) { 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;jUninitialize(); 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; }