/**************************************************************************** * * Copy right: 2020-, Copyrigths of QIXIANG TECH Ltd. * File name: app.c * Description: QX app source file * History: Rev1.0 2020-10-16 * Athuor: chenjie * ****************************************************************************/ //include #include "bsp.h" #include "bsp_custom.h" #include "osasys.h" #include "ostask.h" #include "queue.h" #include "ps_event_callback.h" #include "app.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" //define // app task static stack and control block #define PROC_TASK_STACK_SIZE (1024) //uart def #define Uart_Send_LEN (8) #define Uart_Rece_LEN (16) #define RTE_UART_RX_IO_MODE RTE_UART1_RX_IO_MODE //statement variable extern ARM_DRIVER_USART Driver_USART1; static ARM_DRIVER_USART *USARTdrv = &Driver_USART1; /** \brief usart receive buffer */ uint8_t Uart_Data_buffer[8]; /** \brief usart send buffer */ /** \brief receive timeout flag */ volatile bool isRecvTimeout = false; /** \brief receive complete flag */ volatile bool isRecvComplete = false; uint8_t process0SlpHandler = 0xff; uint8_t process1SlpHandler = 0xff; uint8_t process2SlpHandler = 0xff; /** \brief 电压传输 */ uint8_t Uart_Rece_BattCellU1_U4[8]; uint8_t Uart_Rece_BattCellU5_U8[8]; uint8_t Uart_Rece_BattCellU9_U12[8]; uint8_t Uart_Rece_BattCellU13_U14[8]; uint8_t Uart_Rece_BattT[8]; int16_t Uart_Rece_BattI; uint8_t Uart_Rece_Batt_states[6]; uint16_t Uart_Rece_BattU; uint16_t Uart_Rece_Batt_MaxcellU; uint16_t Uart_Rece_Batt_MincellU; typedef enum { PROCESS1_STATE_IDLE = 0, PROCESS1_STATE_WORK, PROCESS1_STATE_SLEEP }process1SM; typedef enum { PROCESS2_STATE_IDLE = 0, PROCESS2_STATE_WORK, PROCESS2_STATE_SLEEP }process2SM; static StaticTask_t gProcessTask0; static UINT8 gProcessTaskStack0[PROC_TASK_STACK_SIZE]; static StaticTask_t gProcessTask1; static UINT8 gProcessTaskStack1[PROC_TASK_STACK_SIZE]; static StaticTask_t gProcessTask2; static UINT8 gProcessTaskStack2[PROC_TASK_STACK_SIZE]; process1SM gProc1State = PROCESS1_STATE_IDLE; process2SM gProc2State = PROCESS2_STATE_IDLE; #define PROC1_STATE_SWITCH(a) (gProc1State = a) #define PROC2_STATE_SWITCH(a) (gProc2State = a) unsigned int crc_chk(uint8_t* data, uint8_t length) { int j; uint16_t 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; } uint8_t* Uart_Receive_func(Uart_Receive_Type Uart_Receive_Msg) { uint8_t Uart_Rece_buffer[Uart_Rece_LEN]; uint16_t CRC_Reve_buffer; uint16_t CRC_chk_buffer; uint8_t Uart_Send_buffer[8]; uint8_t Rece_Data_Len; Uart_Send_buffer[0] = Uart_Receive_Msg.Bms_Address; Uart_Send_buffer[1] = Uart_Receive_Msg.Bms_Read_Funcode; Uart_Send_buffer[2] = Uart_Receive_Msg.Reg_Begin_H; Uart_Send_buffer[3] = Uart_Receive_Msg.Reg_Begin_L; Uart_Send_buffer[4] = Uart_Receive_Msg.Reg_Num_H; Uart_Send_buffer[5] = Uart_Receive_Msg.Reg_Num_L; CRC_chk_buffer = crc_chk(Uart_Send_buffer,6); Uart_Send_buffer[6] = CRC_chk_buffer; Uart_Send_buffer[7] = CRC_chk_buffer>>8; Uart_Rece_buffer[0]=0xfe; uint32_t timeout=0; USARTdrv->Send(Uart_Send_buffer,8); USARTdrv->Receive(Uart_Rece_buffer,13); Rece_Data_Len = 11; while((isRecvTimeout == false) && (isRecvComplete == false))// 未收到数据不叫时间超时,收到数据但是不全叫时间超时 { timeout++; if (timeout>7000000) { timeout =0; isRecvTimeout = true; break; } } if (isRecvComplete == true) { isRecvComplete = false; CRC_chk_buffer =Uart_Rece_buffer[12]<<8|Uart_Rece_buffer[11]; CRC_Reve_buffer = crc_chk(Uart_Rece_buffer,11); if (CRC_Reve_buffer == CRC_chk_buffer)//满足校验 { for (uint8_t i = 0; i < 8; i++) { Uart_Data_buffer[i]=Uart_Rece_buffer[i+3]; } return Uart_Data_buffer; } else //接收数据的校验不过暂时屏蔽 { for (uint8_t i = 0; i < 8; i++) { Uart_Data_buffer[i]=0xff; } return Uart_Data_buffer; } } if (isRecvTimeout == true)//没收到数据,全部为空值 { Uart_Data_buffer[0] = 0x00; Uart_Data_buffer[1] = 0x00; Uart_Data_buffer[2] = 0x00; Uart_Data_buffer[3] = 0x00; Uart_Data_buffer[4] = 0x00; Uart_Data_buffer[5] = 0x00; Uart_Data_buffer[6] = 0x00; Uart_Data_buffer[7] = 0xff; isRecvTimeout = false; osDelay(1000); return Uart_Data_buffer; } } void USART_callback(uint32_t event) { if(event & ARM_USART_EVENT_RX_TIMEOUT) { isRecvTimeout = true; } if(event & ARM_USART_EVENT_RECEIVE_COMPLETE) { isRecvComplete = true; } } static void process0AppTask(void* arg) { uint32_t inParam = 0xAABBCCDD; uint32_t cnt; slpManSetPmuSleepMode(true,SLP_HIB_STATE,false); slpManApplyPlatVoteHandle("process0slp",&process0SlpHandler); slpManSlpState_t slpstate = slpManGetLastSlpState(); UINT8 Can_index = 0; UINT8 Uart_index = 0; while(1) { osDelay(10);//10ms Can_index++; Uart_index++; if (Uart_index >10)//Uart 100ms 调用一次 { PROC2_STATE_SWITCH(PROCESS2_STATE_WORK); Uart_index = 0; } if (Can_index >=100)//Can 100ms 调用一次 { PROC1_STATE_SWITCH(PROCESS1_STATE_WORK); Can_index = 0; } } } static void process1AppTask(void* arg) { PROC1_STATE_SWITCH(PROCESS1_STATE_IDLE); uint32_t Can_ID; NVIC_EnableIRQ(PadWakeup1_IRQn); Can_InitType param; Can_TxMsgType Can_TxMsg; param.baudrate = CAN_500Kbps; param.mode = REQOP_NORMAL; param.TxStdIDH = 0x00; param.TxStdIDL = 0x00; param.RxStdIDH[0] = 0x00; param.RxStdIDL[0] = 0x00; /*stdid 0000 0000 001x*/ param.RxStdIDH[1] = 0x00; param.RxStdIDL[1] = 0x20; /*stdid 0000 0000 010x */ param.RxStdIDH[2] = 0x00; param.RxStdIDL[2] = 0x40; /*stdid 0000 0000 011x*/ param.RxStdIDH[3] = 0x00; param.RxStdIDL[3] =0x60; /*stdid 0000 0000 100x */ param.RxStdIDH[4] = 0x00; param.RxStdIDL[4] = 0x80; /*stdid 0000 0000 101x*/ param.RxStdIDH[5] = 0x00; param.RxStdIDL[5] =0xa0; param.packType = STD_PACK; HAL_Can_Init(param); int send_index = 0; while(1) { switch(gProc1State) { case PROCESS1_STATE_IDLE: { send_index = 0; FaultDisplay(LED_TURN_OFF); break; } case PROCESS1_STATE_WORK: { switch(send_index) { case 0: { Can_ID = 0x001; for (int i = 0; i < 8; i++) { Can_TxMsg.Data[i] = Uart_Rece_BattCellU1_U4[i]; } Can_TxMsg.stdIDH = Can_ID>>3; Can_TxMsg.stdIDL = Can_ID<<5; Can_TxMsg.DLC = 8; HAL_Can_Transmit(Can_TxMsg); break; } case 1: { Can_ID = 0x012; for (int i = 0; i < 8; i++) { Can_TxMsg.Data[i] = Uart_Rece_BattCellU5_U8[i]; } Can_TxMsg.stdIDH = Can_ID>>3; Can_TxMsg.stdIDL = Can_ID<<5; Can_TxMsg.DLC = 8; HAL_Can_Transmit(Can_TxMsg); break; } case 2: { Can_ID = 0x021; for (int i = 0; i < 8; i++) { Can_TxMsg.Data[i] = Uart_Rece_BattCellU9_U12[i]; } Can_TxMsg.stdIDH = Can_ID>>3; Can_TxMsg.stdIDL = Can_ID<<5; Can_TxMsg.DLC = 8; HAL_Can_Transmit(Can_TxMsg); break; } case 3: { Can_ID = 0x031; for (int i = 0; i < 4; i++) { Can_TxMsg.Data[i] = Uart_Rece_BattCellU13_U14[i]; } Can_TxMsg.Data[4] = 0x00; Can_TxMsg.Data[5] = 0x00; Can_TxMsg.Data[6] = 0x00; Can_TxMsg.Data[7] = 0x00; Can_TxMsg.stdIDH = Can_ID>>3; Can_TxMsg.stdIDL = Can_ID<<5; Can_TxMsg.DLC = 8; HAL_Can_Transmit(Can_TxMsg); break; } case 4: { Can_ID = 0x101; for (int i = 0; i < 4; i++) { Can_TxMsg.Data[i] = Uart_Rece_BattT[i*2+1]; } Can_TxMsg.stdIDH = Can_ID>>3; Can_TxMsg.stdIDL = Can_ID<<5; Can_TxMsg.DLC = 8; HAL_Can_Transmit(Can_TxMsg); break; } case 5: { Can_ID = 0x201; Can_TxMsg.Data[0] = Uart_Rece_BattU>>8; Can_TxMsg.Data[1] = Uart_Rece_BattU; Can_TxMsg.Data[2] = 0x00; Can_TxMsg.Data[3] = 0x00;//外电压 Can_TxMsg.Data[4] = 0x00; Can_TxMsg.Data[5] = 0x00;//累加电压 Can_TxMsg.Data[6] = Uart_Rece_BattI>>8; Can_TxMsg.Data[7] = Uart_Rece_BattI; Can_TxMsg.stdIDH = Can_ID>>3; Can_TxMsg.stdIDL = Can_ID<<5; Can_TxMsg.DLC = 8; HAL_Can_Transmit(Can_TxMsg); break; } default: { PROC1_STATE_SWITCH(PROCESS1_STATE_IDLE); } } send_index ++; FaultDisplay(LED_TURN_ON); break; } case PROCESS1_STATE_SLEEP: { break; } } } } static void process2AppTask(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); int Rece_index = 0; uint8_t *Uart_Reve_Point = NULL; Uart_Receive_Type Uart_Receive_Msg; PROC2_STATE_SWITCH(PROCESS2_STATE_IDLE); while(1) { switch(gProc2State) { case PROCESS2_STATE_IDLE: { Rece_index = 0; NetSocDisplay(3,LED_TURN_OFF); break; } case PROCESS2_STATE_WORK: { Uart_Receive_Msg.Bms_Address = 0x01; Uart_Receive_Msg.Bms_Read_Funcode = 0x03; switch(Rece_index) { case 0://读取电压1-4 { Uart_Receive_Msg.Reg_Begin_H = 0x00; Uart_Receive_Msg.Reg_Begin_L = 0x02; Uart_Receive_Msg.Reg_Num_H = 0x00; Uart_Receive_Msg.Reg_Num_L = 0x04; Uart_Reve_Point = Uart_Receive_func(Uart_Receive_Msg); for(int i =0;i<8;i++) { Uart_Rece_BattCellU1_U4[i] = *(Uart_Reve_Point+i); } break; } case 1://读取电压5-8 { Uart_Receive_Msg.Reg_Begin_H = 0x00; Uart_Receive_Msg.Reg_Begin_L= 0x06; Uart_Receive_Msg.Reg_Num_H = 0x00; Uart_Receive_Msg.Reg_Num_L = 0x04; Uart_Reve_Point = Uart_Receive_func(Uart_Receive_Msg); for(int i =0;i<8;i++) { Uart_Rece_BattCellU5_U8[i] = *(Uart_Reve_Point+i); } break; } case 2: { Uart_Receive_Msg.Reg_Begin_H = 0x00; Uart_Receive_Msg.Reg_Begin_L= 0x0A; Uart_Receive_Msg.Reg_Num_H = 0x00; Uart_Receive_Msg.Reg_Num_L = 0x04; Uart_Reve_Point = Uart_Receive_func(Uart_Receive_Msg); for(int i =0;i<8;i++) { Uart_Rece_BattCellU9_U12[i] = *(Uart_Reve_Point+i); } break; } case 3: { Uart_Receive_Msg.Reg_Begin_H = 0x00; Uart_Receive_Msg.Reg_Begin_L= 0x0E; Uart_Receive_Msg.Reg_Num_H = 0x00; Uart_Receive_Msg.Reg_Num_L = 0x04; Uart_Reve_Point = Uart_Receive_func(Uart_Receive_Msg); for(int i =0;i<8;i++) { Uart_Rece_BattCellU13_U14[i] = *(Uart_Reve_Point+i); } break; } case 4: { Uart_Receive_Msg.Reg_Begin_H = 0x00; Uart_Receive_Msg.Reg_Begin_L= 0x14; Uart_Receive_Msg.Reg_Num_H = 0x00; Uart_Receive_Msg.Reg_Num_L = 0x04; Uart_Reve_Point = Uart_Receive_func(Uart_Receive_Msg); for(int i =0;i<8;i++) { Uart_Rece_BattT[i] = *(Uart_Reve_Point+i); } break; } case 5: { Uart_Receive_Msg.Reg_Begin_H = 0x00; Uart_Receive_Msg.Reg_Begin_L= 0x10; Uart_Receive_Msg.Reg_Num_H = 0x00; Uart_Receive_Msg.Reg_Num_L = 0x04; Uart_Reve_Point = Uart_Receive_func(Uart_Receive_Msg); Uart_Rece_BattI = *(Uart_Reve_Point+0)<<8 | *(Uart_Reve_Point+1); for (int i = 0; i < 6; i++) { Uart_Rece_Batt_states[i] = *(Uart_Reve_Point+2+i); } break; } case 6: { Uart_Receive_Msg.Reg_Begin_H = 0x00; Uart_Receive_Msg.Reg_Begin_L= 0x2B; Uart_Receive_Msg.Reg_Num_H = 0x00; Uart_Receive_Msg.Reg_Num_L = 0x04; Uart_Reve_Point = Uart_Receive_func(Uart_Receive_Msg); Uart_Rece_BattU = *(Uart_Reve_Point+0)<<8 | *(Uart_Reve_Point+1); Uart_Rece_Batt_MaxcellU = *(Uart_Reve_Point+2)<<8 | *(Uart_Reve_Point+3); Uart_Rece_Batt_MincellU = *(Uart_Reve_Point+4)<<8 | *(Uart_Reve_Point+5); break; } default: { PROC2_STATE_SWITCH(PROCESS2_STATE_IDLE); break; } } Rece_index++; NetSocDisplay(3,LED_TURN_ON); break; } case PROCESS2_STATE_SLEEP: { //此处写休眠程序 break; } } } } /** \fn process0Init(void) \brief process0Init function. \return */ void process0Init(void) { osThreadAttr_t task_attr; #ifndef USING_PRINTF if(BSP_GetPlatConfigItemValue(PLAT_CONFIG_ITEM_LOG_CONTROL) != 0) { HAL_UART_RecvFlowControl(false); } #endif memset(&task_attr,0,sizeof(task_attr)); memset(gProcessTaskStack0, 0xA5,PROC_TASK_STACK_SIZE); task_attr.name = "Process0AppTask"; task_attr.stack_mem = gProcessTaskStack0; task_attr.stack_size = PROC_TASK_STACK_SIZE; task_attr.priority = osPriorityNormal;//osPriorityBelowNormal; task_attr.cb_mem = &gProcessTask0;//task control block task_attr.cb_size = sizeof(StaticTask_t);//size of task control block osThreadNew(process0AppTask, NULL, &task_attr); } /** \fn process1Init(void) \brief process1Init function. \return */ void process1Init(void) { osThreadAttr_t task_attr; #ifndef USING_PRINTF if(BSP_GetPlatConfigItemValue(PLAT_CONFIG_ITEM_LOG_CONTROL) != 0) { HAL_UART_RecvFlowControl(false); } #endif memset(&task_attr,0,sizeof(task_attr)); memset(gProcessTaskStack1, 0xA5,PROC_TASK_STACK_SIZE); task_attr.name = "Process1AppTask"; task_attr.stack_mem = gProcessTaskStack1; task_attr.stack_size = PROC_TASK_STACK_SIZE; task_attr.priority = osPriorityNormal;//osPriorityBelowNormal; task_attr.cb_mem = &gProcessTask1;//task control block task_attr.cb_size = sizeof(StaticTask_t);//size of task control block osThreadNew(process1AppTask, NULL, &task_attr); } /** \fn process2Init(void) \brief process2Init function. \return */ void process2Init(void) { osThreadAttr_t task_attr; memset(&task_attr,0,sizeof(task_attr)); memset(gProcessTaskStack2, 0xA5,PROC_TASK_STACK_SIZE); task_attr.name = "Process2AppTask"; task_attr.stack_mem = gProcessTaskStack2; task_attr.stack_size = PROC_TASK_STACK_SIZE; task_attr.priority = osPriorityNormal;//osPriorityBelowNormal; task_attr.cb_mem = &gProcessTask2;//task control block task_attr.cb_size = sizeof(StaticTask_t);//size of task control block osThreadNew(process2AppTask, NULL, &task_attr); } /** \fn appInit(void) \brief appInit function. \return */ void appInit(void *arg) { process0Init(); process1Init(); process2Init(); } /** \fn int main_entry(void) \brief main entry function. \return */ void main_entry(void) { BSP_CommonInit(); osKernelInitialize(); registerAppEntry(appInit, NULL); if (osKernelGetState() == osKernelReady) { osKernelStart(); } while(1); }