/**************************************************************************** * * 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" //全局变量输入区 extern UINT32 Timer_count; extern volatile bool Sleep_flag; extern AppNVMDataType AppNVMData; //全局变量输出区 UartReadMsgType UartReadMsg; osMutexId_t UartMutex = NULL;//Uart数据锁 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(UINT8* Uart_Read_Msg,UINT8* Uart_Recv_Buffer); UINT8 Uart_WriteCmd_func(Uart_Write_Data_Type UartWriteData); UINT16 crc_chk(UINT8* data, UINT8 length); void battSOCDisplay(void); void battErrorStateDisplay(void); void battLockStateDisplay(UINT8 lockState); void SP_BMS_Update_Service(void); BOOL BattHeaterSwitch(UINT8* heaterSwitch); UINT16 encryptionAlgorithm (UINT16 plainText); UINT8 decryptionAlgorithm (UINT16 cipherText); UINT8 Uart_Encrypt_Send(void); //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); //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; Uart_Write_Data_Type UartWriteData; //Uart控制命令 if(UartWriteCmdHandle == NULL)//Uart控制命令传输指针 { UartWriteCmdHandle = osMessageQueueNew(3,sizeof(Uart_Write_Data_Type), NULL); } if(UartMutex == NULL) { UartMutex = osMutexNew(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_PRINTF printf("[%d]Uart Timer 5s:%d\n",__LINE__,Timer_count); #endif if(osMessageQueueGet(UartWriteCmdHandle,&UartWriteData,0,0)==osOK) { #ifdef USING_PRINTF 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; } if(Timer_count-currentTimerCount >= 1) { if(AppNVMData.isBattLocked != 0) { battLockStateDisplay(TRUE); } if(uartReadSuccessFlag) { battSOCDisplay(); battErrorStateDisplay(); } } currentTimerCount = Timer_count; if(BMS_Fota_update_flag) { 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) { UartWriteData.WriteCmd = 0x01; UartWriteData.Data[0] = 0x00; UartWriteData.Data[1] = 0x00; osMessageQueuePut(UartWriteCmdHandle,&UartWriteData,0,1000); } else if (AppNVMData.isBattLocked==FALSE && ((UartReadMsg.data[(0x09+BATT_CELL_VOL_NUM+BATT_TEMP_NUM+2)*2+1])>>1)&0x03==0x00) { UartWriteData.WriteCmd = 0x01; UartWriteData.Data[0] = 0x00; UartWriteData.Data[1] = 0x03; osMessageQueuePut(UartWriteCmdHandle,&UartWriteData,0,1000); } break; } case PROCESS_UART_STATE_READ: { osStatus_t result = osMutexAcquire(UartMutex, osWaitForever); 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; Uart_Recv_LEN = Uart_DataRecv_func((UINT8 *)&Uart_Read_Msg,UartReadMsg.Header); osMutexRelease(UartMutex); if(Uart_Recv_LEN>0) { UartReadMsg.UartFlag = TRUE; } else { UartReadMsg.UartFlag = FALSE; } UartReadMsg.len = Uart_Recv_LEN; PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_IDLE); if((UartReadMsg.data[(0x03+BATT_CELL_VOL_NUM)*2+1]&0x03)==0x02) { BattChrgEndFlag=TRUE; } else { BattChrgEndFlag=FALSE; } #ifdef USING_PRINTF1 printf("\nUart_Recv_buffer: "); for(int i=0;iPowerControl(ARM_POWER_LOW); while(TRUE) { osDelay(60000/portTICK_PERIOD_MS); } break; } } } } //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; } 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(UINT8* Uart_Read_Msg,UINT8* Uart_Recv_Buffer) { UINT16 CRC_Rece_buffer; UINT16 CRC_chk_buffer; UINT16 Data_Len ; UINT8 timeout = 0x00; Data_Len = (*(Uart_Read_Msg+4)|*(Uart_Read_Msg+5))*2+5; CRC_chk_buffer = crc_chk(Uart_Read_Msg,6); *(Uart_Read_Msg+6) = CRC_chk_buffer; *(Uart_Read_Msg+7) = CRC_chk_buffer>>8; USARTdrv->Send(Uart_Read_Msg,8); #ifdef USING_PRINTF printf("Uart_Send_buffer: "); for(int i=0;i<8;i++) { printf("%x ",*(Uart_Read_Msg+i)); } printf("\n"); #endif USARTdrv->Receive(Uart_Recv_Buffer,Data_Len); while(true) { timeout++; if((isRecvTimeout == true) || (isRecvComplete == true)) { break; } else { osDelay(100); if (timeout>=50) { timeout =0; isRecvTimeout = true; } } } #ifdef USING_PRINTF printf("%s[%d]\r\n",__FUNCTION__, __LINE__); printf("timeout = %d\n",timeout); #endif #ifdef USING_PRINTF1 printf("Uart_Rece_buffer: "); for(int i=0;iUninitialize(); 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,0xff,Data_Len); return 0; } } else { memset(Uart_Recv_Buffer,0x00,Data_Len); isRecvTimeout = false; 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 battCellTemp[BATT_TEMP_NUM]; UINT8 maxCellTemp,minCellTemp; UINT8 i =0; UINT8 currentSwitchState = 0; //get the current switch state and the cell temp currentSwitchState = UartReadMsg.data[(0x1C+BATT_CELL_VOL_NUM+(BATT_TEMP_NUM+2))*2+1]&0x01; for(int i=0; i10+40||maxCellTemp>30+40) { *heaterSwitch = 0; isNeedtoSwitch= true; } } return isNeedtoSwitch; } void battSOCDisplay() { static UINT8 workState; static UINT8 currentSoc; 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(UartReadMsg.Header[2]>0) { temp = UartReadMsg.data[(0x03+BATT_CELL_VOL_NUM)*2+1]&0x03; workState = ((temp&0x01)<<01)|(temp>>0x01); currentSoc = UartReadMsg.data[(0x0B+BATT_CELL_VOL_NUM+BATT_TEMP_NUM+2)*2+1]; } #ifdef USING_PRINTF1 printf("current SOC = %d\n",currentSoc); printf("work state = %d\n",workState); #endif lightTimer++; if(workState == 0||workState == 2) //静置或放电状态 { if(currentSoc<=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&¤tSoc<=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(currentSoc>25&¤tSoc<=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(currentSoc>50&¤tSoc<=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(currentSoc>75&¤tSoc<=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(workState == 1) { if(currentSoc<=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&¤tSoc<=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&¤tSoc<=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&¤tSoc<=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&¤tSoc<=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 UINT32 errorState; static UINT8 errorLightTimer = 0; //static UINT32 currentTimerCount=0; UINT8 errorLEDFlashPeriod = 6;//600ms float errorDutyRatio = 0.4; if(AppNVMData.isBattLocked == TRUE) { return; } if(UartReadMsg.Header[2]>0) { errorState = ((UartReadMsg.data[(0x09+BATT_CELL_VOL_NUM+BATT_TEMP_NUM+2)*2])<<8)|0|((UartReadMsg.data[(0x0A+BATT_CELL_VOL_NUM+BATT_TEMP_NUM+2)*2])<<24)|((UartReadMsg.data[(0x0A+BATT_CELL_VOL_NUM+BATT_TEMP_NUM+2)*2+1])<<16); //MEMCPY(&errorState,&(UartReadMsg.data[(0x09+BATT_CELL_VOL_NUM+BATT_TEMP_NUM+2)*2]),4); } errorLightTimer++; //errorState = testErrorState; #ifdef USING_PRINTF1 for(int k=0;k=(UINT8)(errorLEDFlashPeriod*errorDutyRatio) && errorLightTimer=(UINT8)(errorLEDFlashPeriod*errorDutyRatio) && errorLightTimer0) { 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; } } 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