/* * usr_b2pc_msg.c * pc同主机通信 * Created on: 2023年9月18日 * Author: longtengjun */ #include #include #include #include "onechip_include_header.h" char DeviceNum[64] = "mini7 2312230001 v1.1, "; extern uint16_t WriteComm0(uint8_t *data, uint16_t len); uint8_t pc_channel_recv = 0; //接收pc的通道,0:未连接; 1:wifi; 2:串口 uint8_t pc_channel_send = 0; //发给pc的通道,0:未连接; 1:wifi; 2:串口 static uint8_t pc_channel_send_backup = 0; //发给pc的通道备份 // extern float slave_temp; // extern uint8_t other_run_state; // str_error_info_t error_info = {0}; //错误信息 uint8_t pc_send_wait = 0; //数据发送等待,0可以立即发送;>0正在发送请等待 uint8_t pc_send_cmd = 0; //当前发送cmd // extern str_mcu_ack mcu_ack_ctrl; // extern uint32_t timeout_com; // extern uint32_t pc_link_timeout; // extern struct light_band_para_t light_band_para[2]; // extern ProcessStateMachine_t psm; // extern CFG_PARAM_STRUCT g_cfg; // #ifdef ONECHIP_MINI_PLUS // extern CFG_PARAM_STRUCT g_cfg_slave; // #endif // extern float evnTemp; // extern uint32_t connectTcpFlag; // extern uint32_t broadDevFlag; // extern uint16_t scan_qrcode_ropprt; // extern uint8_t wifi_tx_buf[WIFI_TX_BUF_SIZE]; // extern uint16_t wifi_tx_len; static unsigned char seq =0; //字节流转整数,大端模式 uint32_t byte_to_u32(uint8_t *p, int len) { uint32_t temp = 0; for(int i = len-1; i >= 0; i--) { temp <<= 8; temp |= p[i]; } return temp; } uint32_t PackDeviceNum(void){ int len = 0; memset((uint8_t *)&DeviceNum, 0 ,sizeof(DeviceNum)); #ifdef ONECHIP_MINI_ONE my_sprintf(&DeviceNum[len],sizeof(DeviceNum), "Mini7-one,V%d.%d.%d.%d",VERSION_1,VERSION_2,VERSION_3,VERSION_4); #else #ifdef ONECHIP_MINI_PLUS my_sprintf(&DeviceNum[len],sizeof(DeviceNum), "Mini7-plus,V%d.%d.%d.%d",VERSION_1,VERSION_2,VERSION_3,VERSION_4); #else my_sprintf(&DeviceNum[len],sizeof(DeviceNum), "Mini7,V%d.%d.%d.%d",VERSION_1,VERSION_2,VERSION_3,VERSION_4); #endif //ONECHIP_MINI_PLUS #endif //ONECHIP_MINI_ONE strcat(DeviceNum, ","); len = strlen(DeviceNum); hex_to_ascii(get_uid(), &DeviceNum[len], 12); //uid strcat(DeviceNum, ","); strcat(DeviceNum, g_cfg.SN); strcat(DeviceNum, " "); LOG("DeviceNum:%s\n", DeviceNum); } /******************************************************************** * uint16_t b2b_send_to_pc(enum pc_cmd_type cmd, char *data, uint16_t len) * *描述:串口发送 *参数:Devicenum 0-发至主机,1发至从机 *返回:无 *其他:无 *-------------------------------------------------------------------- *记录: ********************************************************************/ uint16_t b2b_send_to_pc(enum pc_cmd_type cmd, char *data, uint16_t len) { uint16_t check; CmdMessage msg; msg.head = 0x55aa; msg.seq = cmd_frame_type_req; msg.cmd = cmd; msg.tail = 0x5a; msg.len = len; check = checkSum(&msg.seq, 4); check += checkSum(data, len); msg.checksum = check & 0xFF; msg.tail = check >> 8; WriteComm0((uint8_t*)&msg, g_uMsgCmdFrameLen); msg.data = data; WriteComm0(data, len); return WriteComm0(&msg.checksum, 2); } /******************************************************************** * uint16_t data_send_to_pc(enum pc_cmd_type cmd, char *data, uint16_t len) * *描述:发生数据到PC *参数:Devicenum 0-发至主机,1发至从机 *返回:无 *其他:无 *-------------------------------------------------------------------- *记录: ********************************************************************/ uint16_t union_data_send_to_pc(struct CmdMessage *pMsg) { uint16_t check; uint16_t try = 0; struct CmdMessage msg; int ret = 0; msg.head = 0x55aa; msg.seq = pMsg->seq; msg.cmd = pMsg->cmd; msg.tail = 0x5a; msg.len = pMsg->len; msg.data = pMsg->data; check = checkSum(&msg.seq, 4); *(unsigned int*)msg.data = Devicenum;/*打包模块编号*/ check += checkSum(msg.data, msg.len); msg.checksum = check & 0xFF; msg.tail = (check >> 8); if(Devicenum) { /*从模块 通过IIC上报,稍后跟新*/ } else { WriteComm0((uint8_t*)&msg, g_uMsgCmdFrameLen); WriteComm0(msg.data, msg.len); return WriteComm0(&msg.checksum, 2); } } /******************************************************************** * uint16_t data_send_to_pc(enum pc_cmd_type cmd, char *data, uint16_t len) * *描述:发生数据到PC *参数:Devicenum 0-发至主机,1发至从机 *返回:无 *其他:无 *-------------------------------------------------------------------- *记录: ********************************************************************/ uint16_t data_send_to_pc(enum pc_cmd_type cmd, char *data, uint16_t len) { uint16_t check; struct CmdMessage msg; int ret = 0; msg.head = 0x55aa; msg.seq = cmd_frame_type_req; msg.cmd = cmd; msg.tail = 0x5a; msg.len = len; msg.data = data; if((len+8) > WIFI_TX_BUF_SIZE){ LOG_E("send_to_pc :%x len:%d error ", cmd, len); return -1; } if(pc_channel_send == 1 && !connectTcpFlag && cmd != PC_CMD_SETIP){ /*UDP 模式,不响应设置IP以为指令*/ return -1; } if((pc_channel_send == 1 && PC_CMD_DATASCOPE == cmd)|| /*网口不上报数据*/ (pc_channel_send != 1 && PC_CMD_SETIP == cmd)) /*串口不广播UDP*/{ return -1; } switch(cmd) { case PC_CMD_QRCODE: case PC_CMD_DATA_UPLOAD: case PC_CMD_REPORT_RESULT: seq++; if(0xff == seq){ seq =1; } msg.seq = seq; break; default: //应答 break; } check = checkSum(&msg.seq, 4); check += checkSum(data, len); msg.checksum = check & 0xFF; msg.tail = (check >> 8); if(check_to_pc_busy()){ memcpy(&wifi_tx_buf[0], (uint8_t*)&msg, g_uMsgCmdFrameLen); memcpy(&wifi_tx_buf[g_uMsgCmdFrameLen], data, len); memcpy(&wifi_tx_buf[g_uMsgCmdFrameLen+len], (uint8_t*)&check, 2); wifi_tx_len = g_uMsgCmdFrameLen+len+2; }else{ return -1; } if((pc_channel_send == 1 || cmd == PC_CMD_SETIP ) && PC_CMD_SETWIFI != cmd) { return WIFI_ReSend(); } else { WriteComm0(wifi_tx_buf, wifi_tx_len); memset(wifi_tx_buf, 0, sizeof(wifi_tx_buf)); } } unsigned int check_to_pc_busy(void){ /*判断是否可以发送,缓冲区为空或者索引为0*/ struct CmdMessage *pMessage = (struct CmdMessage *)wifi_tx_buf; if(pMessage->seq == 0 || pMessage->len == 0){ return 1; } return 0; } ///******************************************************************** // * void data_resend_to_pc(void) // * // *描述:判断缓冲区内容,是否需要重发 // *参数:无 // *返回:无 // *其他:无 // *-------------------------------------------------------------------- // *记录: // ********************************************************************/ void pc_resend_del(uint8_t seq){ struct CmdMessage *pMessage = (struct CmdMessage *)wifi_tx_buf; if(pMessage->seq == seq){ wifi_tx_len = 0; memset(wifi_tx_buf, 0, sizeof(wifi_tx_buf)); } } /******************************************************************** * uint16_t send_Devinf_pc(void) * *描述:发送设备信息到主机,便于主机下法TCP信息 *参数:无 *返回:无 *其他:无 *-------------------------------------------------------------------- *记录: ********************************************************************/ void send_Devinf_pc(void) { uint16_t len = 0; len = strlen(DeviceNum); data_send_to_pc(PC_CMD_SETIP,DeviceNum,len); } #ifdef ONECHIP_MINI_ONE int send_temp_parm(uint8_t cmd, uint8_t *parg) { b2b_send_device(B2B_CMD_THEROM_GOAL_ONCE, parg, 16, !Devicenum); return 1; } int setTemp_response(struct CmdMessage *pMsg, uint8_t result) { // char result = 1; data_send_to_pc(PC_CMD_SETRUNTEMP, &result, 1); } #endif void set_pc_chanel_recv(uint8_t channel) { pc_channel_recv = channel; } void set_pc_chanel_temp() { if(pc_channel_recv == 2) timeout_com = 0; pc_channel_send_backup = pc_channel_send; pc_channel_send = pc_channel_recv; } void reload_pc_chanel() { if(pc_channel_recv > pc_channel_send_backup) //串口优先 { pc_channel_send_backup = pc_channel_recv; } pc_channel_send = pc_channel_send_backup; } void set_pc_chanel(uint8_t channel) { pc_channel_send_backup = channel; pc_channel_send = channel; } /******************************************************************** * int handshake_action(uint8_t cmd, uint8_t *parg) * *描述:握手命令处理 *参数:无 *返回:无 *其他:无 *-------------------------------------------------------------------- *记录: ********************************************************************/ int handshake_action(uint8_t cmd, uint8_t *parg) { if(state_controlword < Hand_Shake_cmd) //上位机会间隔发送握手,保活 { state_controlword = Hand_Shake_cmd; } return 0; } void char_replace(uint8_t *str, int size, uint8_t ch, uint8_t replace) { for(int i = 0; i < size; i++) { if(str[i] == ch) str[i] = replace; } } /******************************************************************** * int wifi_action(uint8_t cmd, uint8_t *parg) * *描述:设置wifi命令处理 *参数:无 *返回:无 *其他:无 *-------------------------------------------------------------------- *记录: ********************************************************************/ int wifi_action(uint8_t cmd, uint8_t *parg) { // char_replace(parg, 64, 0xAA, 0); // char_replace(parg, 64, 0xAD, ' '); wifiCfg_set_new_wifi_param(parg, parg + WIFI_AP_NAME_MAX_LEN); // wifi用户名和密码设置 WIFI_set_ssid(); return 1; } int setState_action(uint8_t cmd, uint8_t *parg) { uint8_t block = *parg++; uint8_t nextState = *parg; if(block==0){ if(SYS_STATE_WORKEND == nextState){ psm.state = SW_move_card; } }else{ /*下发命令,改变从模块状态*/ b2b_send_device(B2B_CMD_STATE_SET, &nextState, sizeof(nextState), 1); } return 1; } /******************************************************************** * int wifi_action(uint8_t cmd, uint8_t *parg) * *描述:设置wifi命令处理 *参数:无 *返回:无 *其他:无 *-------------------------------------------------------------------- *记录: ********************************************************************/ int SN_action(uint8_t cmd, uint8_t *parg) { parg[15] = 0; strcpy(g_cfg.SN, parg); PackDeviceNum(); return cfg_save_cfg_param(); } /******************************************************************** * int seq_selftest_action(uint8_t cmd, uint8_t *parg) * *描述:设备自检处理 *参数:无 *返回:无 *其他:无 *-------------------------------------------------------------------- *记录: ********************************************************************/ int seq_selftest_action(uint8_t cmd, uint8_t *parg) { return 0; } /******************************************************************** * int confirm_result_action(uint8_t cmd, uint8_t *parg) * *描述:设备收到pc的结果响应 *参数:无 *返回:无 *其他:无 *-------------------------------------------------------------------- *记录: ********************************************************************/ int confirm_result_action(uint8_t cmd, uint8_t *parg) { if(Devicenum) { return 0; } if(0 == memcmp(parg,card_param_info.pid, 10 )) state_controlword = result_move_card; return 0; } /******************************************************************** * int default_pc_response(struct CmdMessage *pMsg, uint8_t result) * *描述:默认回应PC *参数:无 *返回:成功->0 失败->-1 *其他:无 *-------------------------------------------------------------------- *记录: ********************************************************************/ int default_pc_response(struct CmdMessage *pMsg, uint8_t result) { if(Devicenum) { return 0; } return data_send_to_pc(pMsg->cmd, &result, 1); } /******************************************************************** * int handshake_response(struct CmdMessage *pMsg, uint8_t result) * *描述:握手回应 *参数:无 *返回:无 *其他:无 *-------------------------------------------------------------------- *记录: ********************************************************************/ int handshake_response(struct CmdMessage *pMsg, uint8_t result) { int len = 0; // PackDeviceNum(); len = strlen(DeviceNum); return data_send_to_pc(pMsg->cmd, (uint8_t*)DeviceNum, len); } int AskState_response(struct CmdMessage *pMsg, uint8_t result) { ANS_State(); } int set_response(struct CmdMessage *pMsg, uint8_t result) { // char wifi_result = 1; // data_send_to_pc(PC_CMD_SETWIFI, &wifi_result, 1); } int setState_response(struct CmdMessage *pMsg, uint8_t result) { // char result = 1; data_send_to_pc(PC_CMD_SETSTATE, &result, 1); } int ans_response(struct CmdMessage *pMsg, uint8_t result) { /*清空需要上位机应答的消息*/ switch(pMsg->cmd){ case PC_CMD_REPORT_REEOR: // unsigned char *data = pMsg->data; // if(*data == Devicenum){ // } clean_error_update(); break; case PC_CMD_UPDATESTATE: clean_state_update(); break; case PC_CMD_QRCODE: clean_QR_update(); break; case PC_CMD_DATA_UPLOAD:{ unsigned char *data = pMsg->data; unsigned int recdex = 0xfffffff; // unsigned char result = *data; // unsigned char part = *(data+1); if( pMsg->len == 6){ recdex = *(data+5); recdex = recdex<<8; recdex += *(data+4); recdex = recdex<<8; recdex += *(data+3); recdex = recdex<<8; recdex += *(data+2); }else{ if(seq == pMsg->seq){ recdex = 0; } } updateData_next(recdex,data); } break; case PC_CMD_REPORT_RESULT:{ unsigned char *data = pMsg->data; // unsigned char result = *data; // unsigned char part = *(data+1); clean_reult_next(data); // if(result){ // /*消息成功,进行跟新*/ // clean_reult_next(part); // } } break; } } int confirm_qrcode_action(uint8_t cmd, uint8_t *parg) { //PC返回成功,才认为扫码成功 scan_qrcode_ropprt = 1; if(*parg == 1) { if(0 == mem_value(&card_param_info_temp, 0 , sizeof(str_card_param_info_t))) { // scan_qrcode_ropprt = 1; LOG_D("rec no card \n\r:"); return -1; } if((psm.state == SW_Scan_Qrcode || psm.state == SW_Chip_Id )) //主机空闲,给自己 { scan_qrcode_done = 1; memcpy(&card_param_info, &card_param_info_temp, sizeof(str_card_param_info_t)); } else { //比较是否跟主模块相同 if(0 == memcmp(&card_param_info, &card_param_info_temp, sizeof(str_card_param_info_t))) { return 0; } //主机不空,下发给从机 card_param_info_temp.envtemp = evnTemp; b2b_send_device(B2B_CMD_REQ_QRCODE, (char *)&card_param_info_temp, sizeof(str_card_param_info_t), 1); } LOG_D("rec start\n\r:"); return 0; } LOG_D("rec no macth\n\r:"); return -1; } int confirm_error_action(uint8_t cmd, uint8_t *parg) { return 0; } int confirm_data_action(uint8_t cmd, uint8_t *parg) { return 0; } const struct PCActionPack mPCActionPack[] = { { .cmd = PC_CMD_HANDSHAKE, .action = handshake_action, .response = handshake_response, .datalen = 0, }, { .cmd = PC_CMD_SETWIFI, .action = wifi_action, .response = set_response, .datalen = 0xff, }, { .cmd = PC_CMD_SETSN, .action = SN_action, .response = handshake_response, .datalen = 7, }, { .cmd = PC_CMD_QRCODE, .action = confirm_qrcode_action, .response = ans_response, .datalen = 0xff, }, { .cmd = PC_CMD_SNANDCARD, .action = confirm_error_action, .datalen = 1, }, { .cmd = PC_CMD_REPORT_RESULT, .action = confirm_result_action, .response = ans_response, .datalen = 0xff, }, { .cmd = PC_CMD_REPORT_REEOR, .action = confirm_error_action, .response = ans_response, .datalen = 0xff, }, { .cmd = PC_CMD_DATA_UPLOAD, .action = confirm_data_action, .response = ans_response, .datalen = 0xff, }, { .cmd = PC_CMD_SETIP, .action = set_IP_action, .response = NULL, .datalen = 0xff, }, { .cmd = PC_CMD_UPDATESTATE, .action = confirm_data_action, .response = ans_response, .datalen = 0xff, }, { .cmd = PC_CMD_ASKSTATE, .action = confirm_data_action, .response = AskState_response, .datalen = 0xff, }, { .cmd = PC_CMD_SETSTATE, .action = setState_action, .response = setState_response, .datalen = 0xff, }, #ifdef ONECHIP_MINI_ONE { .cmd = PC_CMD_SETRUNTEMP, .action = send_temp_parm, .response = setTemp_response, .datalen = 0xff, }, #endif }; /******************************************************************** * int handshake_action(uint8_t cmd, uint8_t *parg) * *描述:握手命令处理 *参数:无 *返回:无 *其他:无 *-------------------------------------------------------------------- *记录: ********************************************************************/ int con_heat_action(uint8_t cmd, uint8_t *parg ) { // CmdMessage *pMsg = (CmdMessageDef *)parg; struct CmdMessage *pMsg = (struct CmdMessage *)parg;; miniConfigPram *pram = (miniConfigPram *)pMsg->data; if(pram->partID == Devicenum){ if( pMsg->cmd == UINON_CMD_MOTORMOVE ){ /*直接透传给从muc处理*/ g_cfg.timeinner = *(float *)(pMsg->data+4) * 100; g_cfg.swingspeed = *(float *)(pMsg->data+8); g_cfg.swingtime = *(float *)(pMsg->data+12) * 100; g_cfg.swingtimeRight = *(float *)(pMsg->data+16) * 100; g_cfg.swingtimePause = *(float *)(pMsg->data+20) * 100; if((1 == *(int *)(pMsg->data+pMsg->len - 4))){ cfg_save_cfg_param(); Motor_Init(); }else{ Motor_mix(g_cfg.timeinner,g_cfg.swingspeed,g_cfg.swingtime,g_cfg.swingtimeRight,g_cfg.swingtimePause); } data_send_to_pc(pMsg->cmd, pMsg->data, pMsg->len); } if( pMsg->cmd == UINON_CMD_MOTORTRETURN ){ /*直接透传给从muc处理*/ uint32_t time = *(float *)(pMsg->data+4) * 10; uint32_t speed = *(float *)(pMsg->data+8) ; data_send_to_pc(pMsg->cmd, pMsg->data, pMsg->len); // sw_st = FIND_GAPNUM; // stateFistin = 1; } #ifdef ONECHIP_MINI_ONE if( pMsg->cmd == UINON_CMD_TEMP_ADJ || pMsg->cmd == UINON_CMD_TEMP_PID || pMsg->cmd == UINON_CMD_TEMP_ADJ_GET || pMsg->cmd == UINON_CMD_TEMP_PID_GET || pMsg->cmd == UINON_CMD_TEMP_START || pMsg->cmd == UINON_CMD_TEMP_STOP){ /*直接透传给从muc处理*/ sendMsgtoSlaveMcu(pMsg); } #endif }else{ #ifdef ONECHIP_MINI_ONE switch(pMsg->cmd){ case UINON_CMD_THEROM_GOAL:{ b2b_send_device(B2B_CMD_THEROM_GOAL, pMsg->data, pMsg->len, !Devicenum); }break; case UINON_CMD_THEROM_OFFSET:{ b2b_send_device(B2B_CMD_THEROM_OFFSET, pMsg->data, pMsg->len, !Devicenum); }break; case UINON_CMD_THEROM_GET:{ b2b_send_device(B2B_CMD_GETTHEROMPRAM_ACK, pMsg->data, pMsg->len, !Devicenum); }break; } /*发送给从模块 稍后实现*/ #endif } return 0; } const struct PCActionPack mUnionActionPack[] = { { .cmd = UINON_CMD_MOTORMOVE, .action = con_heat_action, }, { .cmd = UINON_CMD_MOTORTRETURN, .action = con_heat_action, }, #ifdef ONECHIP_MINI_ONE { .cmd = UINON_CMD_TEMP_ADJ, .action = con_heat_action, }, { .cmd = UINON_CMD_TEMP_PID, .action = con_heat_action, }, { .cmd = UINON_CMD_TEMP_ADJ_GET, .action = con_heat_action, }, { .cmd = UINON_CMD_TEMP_PID_GET, .action = con_heat_action, }, { .cmd = UINON_CMD_TEMP_START, .action = con_heat_action, }, { .cmd = UINON_CMD_TEMP_STOP, .action = con_heat_action, }, { .cmd = UINON_CMD_THEROM_GOAL, .action = con_heat_action, }, { .cmd = UINON_CMD_THEROM_OFFSET, .action = con_heat_action, }, { .cmd = UINON_CMD_THEROM_GET, .action = con_heat_action, }, { .cmd = UINON_CMD_TEMP_DEBUG, .response = handshake_response, }, #endif }; void deal_mUnion_cmd(struct CmdMessage *pMsg) { for (uint8_t i = 0; i < sizeof(mUnionActionPack)/sizeof(mUnionActionPack[0]); i++) { if (mUnionActionPack[i].cmd == pMsg->cmd ) { uint8_t ret = mUnionActionPack[i].action( pMsg->cmd,(uint8_t *)pMsg); if (mUnionActionPack[i].response) { mUnionActionPack[i].response(pMsg, ret); } break; } } } /******************************************************************** * void query_pc_cmd(struct CmdMessage *pMsg) * *描述:处理PC命令 *参数:无 *返回:无 *其他:无 *-------------------------------------------------------------------- *记录: ********************************************************************/ void query_pc_cmd(struct CmdMessage *pMsg) { for (uint8_t i = 0; i < sizeof(mPCActionPack)/sizeof(mPCActionPack[0]); i++) { if (mPCActionPack[i].cmd == pMsg->cmd && (mPCActionPack[i].datalen == pMsg->len || mPCActionPack[i].datalen == 0xff)) //防止接收到其他设备的数据帧 { if(pc_send_cmd == mPCActionPack[i].cmd) pc_send_wait = 0; if(mPCActionPack[i].cmd != 1) { pc_resend_del(pMsg->seq); LOG_I("\n<-- pc cmd %x %d \n", pMsg->cmd, pMsg->seq); } pMsg->data[pMsg->len] = 0; uint8_t ret = mPCActionPack[i].action(mPCActionPack[i].cmd, pMsg->data); if (mPCActionPack[i].response) { mPCActionPack[i].response(pMsg, ret); } if(!(pc_channel_recv == 1 && !connectTcpFlag)){ pc_link_timeout = 0; //确保TCP通信上在变灯 } break; } } }