#include "app.h" #include "app_hart.h" #include "mode.h" #include "mode_diagnosis.h" #include "menus.h" specification_table_data_t spec_table_data __attribute__((section("NOINIT"), zero_init)); mode_diagnosis_test_t diagnosis_test; /** * @brief 更新映射表 * @return {*} * @note Failure(故障):3 Function Check(功能检查):5 Out of Specification(超出规格):4 Maintenance Required(需要维护):1 */ static void update_compression_state_mapping_table(hart_condensed_status_map_u *const map) { DBG_ASSERT(map != NULL __DBG_LINE); // 举例:当前输入电流 这里判断上限和下限 if (get_diagnosis_fault_result(DIAGNOSIS_INPUT) == FAIL) { map->bits.u1.csm_loop_current = HART_STATE_COMMAND_31_FAILURE; } else { if (get_diagnosis_fault_result(DIAGNOSIS_INPUT) == FAIL) { map->bits.u1.csm_loop_current = HART_STATE_COMMAND_31_FAILURE; } } } /** * @brief 更新其他状态 * * 根据当前情况更新其他状态信息。 * * @param status 指向其他状态结构体的指针 */ static void update_other_status(hart_other_status_u *const status) { DBG_ASSERT(status != NULL __DBG_LINE); // 举例:参考电压故障 // status->bits.hard_failures.stem_position_sensor_fail = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_MAGNET); // status->bits.hard_failures.pressure_sensor_fail = get_diagnosis_fault_result(DIAGNOSIS_PRESS_SENSOR); // status->bits.hard_failures.temp_sensor_fail = get_diagnosis_fault_result(DIAGNOSIS_TEMPERATURE_SENSOR); // status->bits.hard_failures.nvm_alert = get_diagnosis_fault_result(DIAGNOSIS_MICRO_LOOP); // status->bits.hard_failures.drive_current_fail = get_diagnosis_fault_result(DIAGNOSIS_DRIVE_SIGNAL); // status->bits.hard_failures.ref_voltage_fail_and_ram_fail = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_VREF); // status->bits.hard_failures.mlfb_sensor_fail_and_no_free_time = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_MICRO_LOOP); // status->bits.hard_failures.flash_crc_error = get_diagnosis_fault_result_of_enable_state(DIAGNOSIS_FLASH_INTEGRITY); // status->bits.status_integ_1.auto_cal_in_progress6k_and_auto_tune_in_progress6k = (get_diagnosis_fault_result_of_enable_state(INDICATE_AUTO_CALIBRATION) || get_diagnosis_fault_result_of_enable_state(INDICATE_CALIBRATION)); if (get_diagnosis_fault_result(DIAGNOSIS_VREF) == FAIL) { status->bits.hard_failures.ref_voltage_fail_and_ram_fail = FAIL; } else { // RAM故障:这里不检测RAM故障 } } // 133-获取打开的文件信息 static BOOL hart_read_file_information_req(hart_user_req_t *const req) { hart_read_file_information_t rsp; hart_command_133_t *cmd = &req->data.command_133; osel_memset((uint8_t *)&rsp, 0, sizeof(hart_read_file_information_t)); switch (cmd->file_id) { case DVC_FILE_ID_DIAG_DATA_BUFFER: rsp.readwrite_bytes = mode_diagnosis_get_storage()->file_size_written; rsp.max_bytes = mode_diagnosis_get_storage()->file_size; rsp.write_access_control = mode_diagnosis_get_storage()->file_status; break; default: break; } // 回复数据 rsp.readwrite_bytes = S2B_UINT16(rsp.readwrite_bytes); rsp.max_bytes = S2B_UINT16(rsp.max_bytes); req->rsp.len = sizeof(hart_read_file_information_t); osel_memset((uint8_t *)&req->rsp.pbuf, 0, req->rsp.len); osel_memcpy(req->rsp.pbuf, (uint8_t *)&cmd, req->rsp.len); return TRUE; } /** * @brief 134-处理HART读取文件内容请求 * 读取内存表数据 * @param[in] req HART读取文件内容请求 * @return TRUE or FALSE */ static BOOL hart_file_read_req(hart_user_req_t *const req) { uint8_t offset = 0; BOOL ret = FALSE; hart_command_134_t *cmd = &req->data.command_134; switch (cmd->file_index) { case DVC_FILE_ID_CUSTOM_CHAR: { uint16_t setpoiont = 0; uint16_t value = 0; custom_property_table_t *p = (custom_property_table_t *)&udevice.custom_property_table; req->rsp.pbuf[offset] = p->points; offset += 1; for (uint8_t i = 0; i < p->points; i++) { setpoiont = S2B_UINT16(p->setpoint[i]); osel_memcpy(&req->rsp.pbuf[offset], (uint8_t *)&setpoiont, sizeof(uint16_t)); offset += sizeof(uint16_t); } for (uint8_t i = 0; i < p->points; i++) { value = S2B_UINT16(p->value[i]); osel_memcpy(&req->rsp.pbuf[offset], (uint8_t *)&value, sizeof(uint16_t)); offset += sizeof(uint16_t); } req->rsp.len = offset; break; } case DVC_FILE_ID_DIAG_DATA_BUFFER: { if (cmd->read_length == 0) { return FALSE; } req->rsp.len = 0; osel_memset((uint8_t *)&req->rsp.pbuf, 0, HART_RESPONSE_MAX_LEN); ret = mode_diagnosis_file_read(cmd->file_offset, cmd->read_length, req->rsp.pbuf, &req->rsp.len); if (ret == FALSE) { req->rsp.len = 0; } break; } default: return FALSE; } return TRUE; } /** * @brief 135-处理HART写入文件内容请求 * 写入数据到内存表 * @param[in] req HART写入文件内容请求 * @return TRUE or FALSE */ static BOOL hart_file_write_req(hart_user_req_t *const req) { uint8_t offset = 0, remain = 0; hart_command_135_t *cmd = &req->data.command_135; switch (cmd->file_index) { case DVC_FILE_ID_CUSTOM_CHAR: { uint16_t value = 0; uint8_t *source_ptr = cmd->pbuf; uint8_t *target_ptr = (uint8_t *)&udevice.custom_property_table; if (cmd->address == 0x0000) { *target_ptr = *source_ptr++; target_ptr += sizeof(udevice.custom_property_table.points); remain = req->data_length - 3 - sizeof(udevice.custom_property_table.points); // 减去已经读取的points和剩余数据头 } else { remain = req->data_length - 3; // 根据地址计算剩余数据长度 target_ptr += cmd->address; // 移动到正确的目标位置 } for (uint8_t i = 0; i < (remain >> 1) && i < udevice.custom_property_table.points; i++) { // 防止越界 osel_memcpy((uint8_t *)&value, source_ptr, sizeof(uint16_t)); value = B2S_UINT16(value); osel_memcpy(target_ptr, (uint8_t *)&value, sizeof(uint16_t)); source_ptr += sizeof(uint16_t); target_ptr += sizeof(uint16_t); } // 回复数据 offset = 0; target_ptr = (uint8_t *)&udevice.custom_property_table; req->rsp.len = req->data_length; req->rsp.pbuf[offset++] = cmd->file_index; uint16_t address = S2B_UINT16(cmd->address); osel_memcpy(&req->rsp.pbuf[offset], (uint8_t *)&address, sizeof(uint16_t)); offset += sizeof(uint16_t); if (cmd->address == 0x0000) { req->rsp.pbuf[offset++] = udevice.custom_property_table.points; target_ptr += sizeof(udevice.custom_property_table.points); } else { target_ptr += cmd->address; // 移动到正确的目标位置 } for (uint8_t i = 0; i < (remain >> 1); i++) { osel_memcpy((uint8_t *)&value, target_ptr, sizeof(uint16_t)); value = B2S_UINT16(value); osel_memcpy(&req->rsp.pbuf[offset], (uint8_t *)&value, sizeof(uint16_t)); offset += sizeof(uint16_t); target_ptr += sizeof(uint16_t); } break; } case DVC_FILE_ID_FACTORY_DEFAULTS: // TODO return FALSE; case DVC_FILE_ID_PARAMETER_IMPORT: // TODO return FALSE; default: return FALSE; } return TRUE; } // 136-读取/解除/写入EEPROM static BOOL hart_epprom_multiple_operations(hart_user_req_t *const req) { hart_command_136_t *cmd = &req->data.command_136; eeprom_lock_state_e state = EEPROM_STATE_UNLOCK; switch (cmd->sub_cmd) { case EEPROM_COMMAND_WRITE: state = (eeprom_lock_state_e)cmd->lock_type; break; case EEPROM_COMMAND_UNLOCK: state = EEPROM_STATE_UNLOCK; break; case EEPROM_COMMAND_READ: state = EEPROM_STATE_DIAGNOSTIOCS; break; default: break; } // 回复数据 req->rsp.len = 1; req->rsp.pbuf[0] = (uint8_t)state; return TRUE; } /** * @brief 142-处理HART自整定请求 * * @param[in] req HART自整定请求 * @return TRUE or FALSE */ static BOOL hart_tuning_req(hart_user_req_t *const req) { hart_command_142_t *cmd = &req->data.command_142; if (cmd->code == HART_TUNING_EXIT) { DBG_ASSERT(mode_get()->interface_req.mode_adjust_stop != NULL __DBG_LINE); mode_get()->interface_req.mode_adjust_stop(); mode_get()->interface_req.mode_process_start(); params_restart_set(PARAMS_RESET_PRESSURE_SENSOR); rt_data.flag.bits.tuning_enter = FALSE; rt_data.flag.bits.auto_tuning_enter = FALSE; } else if (cmd->code == HART_TUNING_AUTO) { DBG_ASSERT(mode_get()->interface_req.mode_adjust_stop != NULL __DBG_LINE); mode_get()->interface_req.mode_adjust_stop(); mode_get()->interface_req.mode_adjust_start(); mode_get()->adjust_initiate = ADJUST_INITIATE_EXTERNAL; rt_data.flag.bits.auto_tuning_enter = TRUE; } else { if (cmd->code == HART_TUNING_ENTER) { rt_data.flag.bits.tuning_enter = TRUE; } return TRUE; } return TRUE; } // 109-突发模式控制 static BOOL hart_burst_mode_control_req(hart_user_req_t *const req) { hart_command_109_t *cmd = &req->data.command_109; udevice.burst_mode = cmd->burst_mode == FALSE ? FALSE : TRUE; switch (cmd->message_no) { case 0: /* code */ break; case 1: /* code */ break; case 2: /* code */ break; default: break; } uint16_t year = rt_save.real_time.date.year; uint8_t month = rt_save.real_time.date.month; uint8_t day = rt_save.real_time.date.day; uint8_t hour = rt_save.real_time.date.hour; uint8_t minute = rt_save.real_time.date.minute; uint8_t second = rt_save.real_time.date.second; hart_storage_variable_t *p = &hart_device_attribute.flash_variable; uint8_t message[HART_PACKED32_LEN] = ""; sprintf((char *)message, "BURST %d-%d %02d-%02d-%02d %02d:%02d:%02d", cmd->burst_mode, cmd->message_no, year, month, day, hour, minute, second); osel_memcpy(p->message, message, sizeof(message)); // 消息 // 回复数据 req->rsp.len = sizeof(hart_command_109_t); osel_memset((uint8_t *)&req->rsp.pbuf, 0, HART_RESPONSE_MAX_LEN); osel_memcpy(req->rsp.pbuf, (uint8_t *)cmd, req->rsp.len); return TRUE; } // 144-读取阀门序列号 static BOOL hart_read_valve_sn_req(hart_user_req_t *const req) { req->rsp.len = VALVE_SERIAL_NUM_LEN; osel_memset((uint8_t *)&req->rsp.pbuf, 0, HART_RESPONSE_MAX_LEN); osel_memcpy(req->rsp.pbuf, (uint8_t *)udevice.valve_serial_num, req->rsp.len); return TRUE; } // 145 读取仪器序列号 static BOOL hart_read_device_sn_req(hart_user_req_t *const req) { req->rsp.len = INST_SERIAL_NUM_LEN; osel_memset((uint8_t *)&req->rsp.pbuf, 0, HART_RESPONSE_MAX_LEN); osel_memcpy(req->rsp.pbuf, (uint8_t *)udevice.dev_serial_num, req->rsp.len); return TRUE; } // 147-读取设备等级 static BOOL hart_read_device_level_req(hart_user_req_t *const req) { hart_command_147_t cmd; cmd.seed = 0; cmd.level = S2B_UINT16(udevice.dev_usfeatures); cmd.update_count = 0; req->rsp.len = sizeof(hart_command_147_t); osel_memset((uint8_t *)&req->rsp.pbuf, 0, HART_RESPONSE_MAX_LEN); osel_memcpy(req->rsp.pbuf, (uint8_t *)&cmd, req->rsp.len); return TRUE; } // 149-设置仪器时间 static BOOL hart_set_dev_time_req(hart_user_req_t *const req) { uint32_t base_secs = HART_BASE_SECS; // 1980-01-01 0:0:0 hart_command_149_t rsp; hart_command_149_t *cmd = &req->data.command_149; rtc_date_t date; rtc_time_t time; stamp2time(base_secs + cmd->secs, &date, &time); // 设置时钟 set_real_time(date.year, date.month, date.day, time.hour, time.minute, time.second); // 回复数据 date.year = rt_save.real_time.date.year; date.month = rt_save.real_time.date.month; date.day = rt_save.real_time.date.day; time.hour = rt_save.real_time.date.hour; time.minute = rt_save.real_time.date.minute; time.second = rt_save.real_time.date.second; rsp.secs = time2stamp(&date, &time) - base_secs; rsp.secs = S2B_UINT32(rsp.secs); req->rsp.len = sizeof(hart_command_149_t); osel_memset((uint8_t *)&req->rsp.pbuf, 0, HART_RESPONSE_MAX_LEN); osel_memcpy(req->rsp.pbuf, (uint8_t *)&rsp, req->rsp.len); return TRUE; } // 150-读取仪器时间 static BOOL hart_read_dev_time_req(hart_user_req_t *const req) { uint32_t base_secs = HART_BASE_SECS; // 1980-01-01 0:0:0 hart_command_150_t rsp; rtc_date_t date; rtc_time_t time; // 回复数据 date.year = rt_save.real_time.date.year; date.month = rt_save.real_time.date.month; date.day = rt_save.real_time.date.day; time.hour = rt_save.real_time.date.hour; time.minute = rt_save.real_time.date.minute; time.second = rt_save.real_time.date.second; rsp.secs = time2stamp(&date, &time) - base_secs; rsp.secs = S2B_UINT32(rsp.secs); rsp.reserve = 0; ///< 保留 req->rsp.len = sizeof(hart_command_150_t); osel_memset((uint8_t *)&req->rsp.pbuf, 0, HART_RESPONSE_MAX_LEN); osel_memcpy(req->rsp.pbuf, (uint8_t *)&rsp, req->rsp.len); return TRUE; } // 151-读取版本信息 static BOOL hart_read_version_req(hart_user_req_t *const req) { // 当前指令没有任何意义,只是为了模拟协议 hart_command_151_t cmd; osel_memset((uint8_t *)&cmd, 0, sizeof(hart_command_151_t)); cmd.nvm_version = 1; cmd.valvelink_version = 1; cmd.date[0] = 0x05; cmd.date[1] = 0x20; cmd.date[2] = 0x23; // 这里是将十六进制按照十进制显示 cmd.reserve[0] = 0xef; cmd.reserve[1] = 0x8a; cmd.reserve[2] = 0x01; req->rsp.len = sizeof(hart_command_151_t); osel_memset((uint8_t *)&req->rsp.pbuf, 0, HART_RESPONSE_MAX_LEN); osel_memcpy(req->rsp.pbuf, (uint8_t *)&cmd, req->rsp.len); return TRUE; } // 153-读取校准记录 static BOOL hart_read_calibration_record_req(hart_user_req_t *const req) { hart_command_153_t cmd; osel_memset((uint8_t *)&cmd, 0, sizeof(hart_command_153_t)); osel_memcpy((uint8_t *)&cmd, (uint8_t *)&udevice.calib_record, sizeof(hart_command_153_t)); req->rsp.len = sizeof(hart_command_153_t); osel_memset((uint8_t *)&req->rsp.pbuf, 0, HART_RESPONSE_MAX_LEN); osel_memcpy(req->rsp.pbuf, (uint8_t *)&cmd, req->rsp.len); return TRUE; } // 168-读取部分行程报警 static BOOL hart_read_partial_stroke_alarm_req(hart_user_req_t *const req) { hart_command_168_t cmd; osel_memset((uint8_t *)&cmd, 0, sizeof(hart_command_168_t)); osel_memcpy(cmd.pbuf, (uint8_t *)udevice.pst_prohibit_detail, ARRAY_LEN(udevice.pst_prohibit_detail)); req->rsp.len = sizeof(hart_command_168_t); osel_memset((uint8_t *)&req->rsp.pbuf, 0, HART_RESPONSE_MAX_LEN); osel_memcpy(req->rsp.pbuf, (uint8_t *)&cmd, req->rsp.len); return TRUE; } // 170-读取制造信息序列号 static BOOL hart_read_manufacturing_sn_req(hart_user_req_t *const req) { uint8_t *pbuf = (uint8_t *)req->rsp.pbuf; osel_memset(pbuf, 0, HART_RESPONSE_MAX_LEN); uint8_t offset = 0; // 类型 pbuf[offset++] = req->data.command_170.code; req->rsp.len = 1; // 数据 switch (req->data.command_170.code) { case HART_MAN_INFO: osel_memcpy((uint8_t *)&pbuf[offset], (uint8_t *)udevice.man_info_serial_num, MAN_SERIAL_NUM_LEN); break; case HART_MAN_SCHEME: osel_memcpy((uint8_t *)&pbuf[offset], (uint8_t *)udevice.man_scheme_serial_num, MAN_SERIAL_NUM_LEN); break; default: return FALSE; } req->rsp.len += MAN_SERIAL_NUM_LEN; return TRUE; } // 基金会测试指令 187 static BOOL hart_test_req(hart_user_req_t *const req) { uint8_t *pbuf = (uint8_t *)req->rsp.pbuf; osel_memset(pbuf, 0, HART_RESPONSE_MAX_LEN); uint8_t offset = 0; // 类型 pbuf[offset++] = req->data.command_187.code; req->rsp.len = 1; switch (req->data.command_187.code) { case COMMAND_187_CLEAR_MORE_STATUS_BIT_AND_WRITE_PROTECT_OFF: // 清除更多状态位并关闭写保护 osel_memset((uint8_t *)&hart_device_attribute.device_status, 0, sizeof(hart_device_status_t)); hart_additional_device_status_crc_init(); hart_device_attribute.flash_variable.write_protect_code = WRITE_PROTECT_CODE_NOT_WRITE_PROTECT; hart_storage_write_item(HART_STORAGE_PARAMS, HPB_WRITE_PROTECT_CODE, (uint8_t *)&hart_device_attribute.flash_variable.write_protect_code); hart_device_status_set_operational_state(DEVICE_OPERATIONAL_STATE_7); break; case COMMAND_187_SET_MORE_STATUS_AVAILABLE_STATUS_BIT: // 请更改设备条件以设置“更多状态可用”状态位 hart_device_attribute.device_status.additional_device_status.extended_device_status = EXTENDED_DEVICE_STATUS_1; hart_device_status_set_operational_state(DEVICE_OPERATIONAL_STATE_5); break; case COMMAND_187_PLACE_DEVICE_INTO_WRITE_PROTECT: // 将设备置于写保护状态 hart_device_attribute.flash_variable.write_protect_code = WRITE_PROTECT_CODE_WRITE_PROTECT; hart_storage_write_item(HART_STORAGE_PARAMS, HPB_WRITE_PROTECT_CODE, (uint8_t *)&hart_device_attribute.flash_variable.write_protect_code); hart_device_status_set_operational_state(DEVICE_OPERATIONAL_STATE_7); break; case COMMAND_187_RESET_IT_IN_COMMAND_48: // 请更改设备条件以重置命令48中设置的状态 hart_device_attribute.device_status.additional_device_status.extended_device_status = EXTENDED_DEVICE_STATUS_0; hart_additional_device_status_crc_init(); hart_device_status_clr_operational_state(DEVICE_OPERATIONAL_STATE_5); break; default: break; } return TRUE; } // 200-读取NVW非易失性存储器数据 static BOOL hart_read_nvw_data_req(hart_user_req_t *const req) { uint8_t *pbuf = (uint8_t *)req->rsp.pbuf; osel_memset(pbuf, 0, HART_RESPONSE_MAX_LEN); /* 内容暂未实现 */ req->rsp.len += B2S_UINT16(req->data.command_200.length - 2); return FALSE; } /** * @brief 155-处理HART模式诊断请求 * * @param[in] req HART模式诊断请求 * @return TRUE or FALSE */ static BOOL hart_mode_diagnosis_req(hart_user_req_t *const req) { hart_command_155_t *cmd = &req->data.command_155; hart_diagnosis_t diag; BOOL ret = FALSE; if (udevice.control_mode != TEST_CTRL_MODE) // 在执行诊断前先需要设置控制模式 { return ret; } osel_memcpy((uint8_t *)&diag, cmd->pbuf, sizeof(hart_diagnosis_t)); diag.target = B2S_UINT16(diag.target); diag.ramp = B2S_UINT16(diag.ramp); diag.points = B2S_UINT16(diag.points); if (diag.diag_type != DIAG_TYPE_OFFLINE_COMMANDED) { return ret; } if (diag.ramp != 0 && diag.points == 0) { return ret; } mode_diagnosis_file_head_u head; osel_memset((uint8_t *)&head.slope, 0, sizeof(mode_diagnosis_slop_file_head_t)); osel_memcpy(head.slope.variable_code, diag.variable_code, HART_PACKED4_LEN); // 设备变量 head.slope.sampling_time = diag.sampling_time; // 采样时间 head.slope.target = diag.target; // 目标位置 head.slope.ramp = diag.ramp; // 斜率 head.slope.points = diag.points; mode_get()->interface_req.mode_process_start(); ret = mode_diagnosis_start(MODE_DIAGNOSIS_TYPE_SLOPE_STEP, &head); if (ret == TRUE) { gui_clr(); mode_enter_test(TEST_ITEM_DIAGNOSIS); } return ret; } /** * @brief 156-读取诊断状态 * * @param[in] req HART模式诊断请求 * @return TRUE or FALSE */ static BOOL hart_read_diagnosis_state_req(hart_user_req_t *const req) { diagnosis_state_u state; state.data = 0; // 测试数据 state.bits.is_in_diagnosis = FALSE; state.bits.trigger_status = TRUE; state.bits.data_compression_enabled = FALSE; state.bits.diag_type = diagnosis_test.diag_type; req->rsp.len = sizeof(diagnosis_state_u); req->rsp.pbuf[0] = state.data; return TRUE; } /** * @brief 162-设置气源压力/A口/B口 * * @param[in] req HART模式诊断请求 * @return TRUE or FALSE */ static BOOL hart_set_pressure_req(hart_user_req_t *const req) { hart_command_162_t *cmd = &req->data.command_162; pressure_type_e index = PRESSURE_PARAM_S; if (cmd->press_type == 0x08) ///< 气源压力 { index = PRESSURE_PARAM_S; } else if (cmd->press_type == 0x02) ///< A口 { index = PRESSURE_PARAM_A; } else ///< B口 { index = PRESSURE_PARAM_B; } if (cmd->press_value == 0) { set_pressure_min(cmd->press_unit, cmd->press_value, index); } else { set_pressure_max(cmd->press_unit, cmd->press_value, index); } // 回复数据 req->rsp.len = sizeof(hart_command_162_t); ///< 返回数据长度 osel_memset((uint8_t *)&req->rsp.pbuf, 0, HART_RESPONSE_MAX_LEN); cmd->press_value = S2B_FLOAT32(cmd->press_value); osel_memcpy(req->rsp.pbuf, (uint8_t *)cmd, req->rsp.len); ///< 返回数据 return TRUE; } /** * @brief 157-处理HART模式诊断停止请求 * * @return TRUE or FALSE */ static BOOL hart_mode_diagnosis_stop_req(void) { mode_diagnosis_stop(); menus_jump_asynchronous(MENUS_WORK, TRUE); return TRUE; } /** * @brief 158-在线诊断测试 * * @return TRUE or FALSE */ static BOOL hart_mode_diagnosis_test_req(hart_user_req_t *const req) { hart_command_158_t *cmd = &req->data.command_158; if (cmd->diagnostic_type != DIAG_TYPE_ONLINE_COMMANDED) { return FALSE; } mode_diagnosis_file_head_u head; osel_memset((uint8_t *)&head.online, 0, sizeof(mode_diagnosis_online_file_head_t)); osel_memcpy(head.online.variable_code, cmd->variable_code, HART_PACKED4_LEN); // 设备变量 head.online.sampling_time = cmd->sampling_time; // 采样时间 head.online.points = cmd->points; // 总点数 return mode_diagnosis_start(MODE_DIAGNOSIS_TYPE_ONLINE, &head); } /** * @brief 写入校准记录 * * @param[in] req HART操作消息请求 * @return TRUE or FALSE */ static BOOL hart_set_calibration_record_req(hart_user_req_t *const req) { hart_command_167_t *cmd = &req->data.command_167; osel_memcpy((uint8_t *)&udevice.calib_record, (uint8_t *)cmd, sizeof(hart_command_167_t)); return TRUE; } // 143-设置阀门序列号 static BOOL hart_set_valve_sn_req(hart_user_req_t *const req) { hart_command_143_t *cmd = &req->data.command_143; osel_memcpy((uint8_t *)udevice.valve_serial_num, cmd->pbuf, ARRAY_LEN(udevice.valve_serial_num)); req->rsp.len = ARRAY_LEN(udevice.valve_serial_num); osel_memset((uint8_t *)&req->rsp.pbuf, 0, HART_RESPONSE_MAX_LEN); osel_memcpy(req->rsp.pbuf, (uint8_t *)udevice.valve_serial_num, req->rsp.len); return TRUE; } // 154-设置仪器序列号 static BOOL hart_set_dev_sn_req(hart_user_req_t *const req) { hart_command_154_t *cmd = &req->data.command_154; osel_memcpy((uint8_t *)udevice.dev_serial_num, cmd->pbuf, ARRAY_LEN(udevice.dev_serial_num)); req->rsp.len = ARRAY_LEN(udevice.dev_serial_num); osel_memset((uint8_t *)&req->rsp.pbuf, 0, HART_RESPONSE_MAX_LEN); osel_memcpy(req->rsp.pbuf, req->data.command_143.pbuf, req->rsp.len); hart_long_addr_set(); hart_storage_write_item(HART_STORAGE_PARAMS, HPB_LONG_ADDRESS, hart_device_attribute.flash_variable.long_address); return TRUE; } // 138-读取其他状态 static BOOL hart_read_other_status_req(hart_user_req_t *const req) { hart_other_status_u status; osel_memset((uint8_t *)&status, 0, sizeof(hart_other_status_u)); update_other_status(&status); req->rsp.len = sizeof(hart_other_status_u); osel_memset((uint8_t *)&req->rsp.pbuf, 0, HART_RESPONSE_MAX_LEN); osel_memcpy(req->rsp.pbuf, (uint8_t *)&status, req->rsp.len); return TRUE; } // 140-读取触发器定义的内容 static BOOL hart_read_trigger_definition_req(hart_user_req_t *const req) { hart_read_trigger_definition_t cmd; osel_memset((uint8_t *)&cmd, 0, sizeof(hart_read_trigger_definition_t)); /****************测试数据****************/ cmd.start_addr = req->data.command_140.start_addr; cmd.trigger_type = diagnosis_test.diag_type; cmd.variable_1 = diagnosis_test.v1; cmd.variable_2 = diagnosis_test.v2; cmd.variable_3 = diagnosis_test.v3; cmd.variable_4 = diagnosis_test.v4; cmd.acquisition_time = diagnosis_test.collection_time; cmd.data_points = diagnosis_test.total_data_points; cmd.trigger_enable = 0x77; cmd.unknow = 0x8899aabb; /**************************************/ /*大小端转换*/ cmd.unknow = S2B_UINT32(cmd.unknow); cmd.data_points = S2B_UINT16(cmd.data_points); cmd.start_addr = S2B_UINT16(cmd.start_addr); req->rsp.len = sizeof(hart_read_trigger_definition_t); osel_memset((uint8_t *)&req->rsp.pbuf, 0, req->rsp.len); osel_memcpy(req->rsp.pbuf, (uint8_t *)&cmd, req->rsp.len); return TRUE; } // 146-读取标准跨度信息(不实现功能) static BOOL hart_read_standard_span_req(hart_user_req_t *const req) { hart_standard_span_information_t span; osel_memset((uint8_t *)&span, 0, sizeof(hart_standard_span_information_t)); span.upper_limit_of_span = 0x2800; span.lower_limit_of_span = 0x0800; span.flash_address = 0x0C9F; span.download_address = 0x0211; span.upper_limit_of_span = S2B_UINT16(span.upper_limit_of_span); span.lower_limit_of_span = S2B_UINT16(span.lower_limit_of_span); span.flash_address = S2B_UINT16(span.flash_address); span.download_address = S2B_UINT16(span.download_address); req->rsp.len = sizeof(hart_standard_span_information_t); osel_memset((uint8_t *)&req->rsp.pbuf, 0, HART_RESPONSE_MAX_LEN); osel_memcpy(req->rsp.pbuf, (uint8_t *)&span, req->rsp.len); return TRUE; } // 523-扩展指令(读取压缩状态映射) static BOOL hart_read_compression_state_mapping_req(hart_user_req_t *const req) { hart_condensed_status_map_u map; osel_memset((uint8_t *)&map, 0, sizeof(hart_condensed_status_map_u)); uint8_t address = req->data.command_523.address * 0.5f; uint8_t count = req->data.command_523.count * 0.5f; // 读取状态个数,根据hart_condensed_status_map_u中的数据类型定义1个字节分为2个状态,这里不考虑存在奇数个状态查询的情况 hart_command_523_t command_523_rsp; if (address > ARRAY_LEN(map.data)) { return FALSE; } osel_memcpy((uint8_t *)&command_523_rsp, (uint8_t *)&req->data.command_523, sizeof(hart_command_523_t)); osel_memcpy(req->rsp.pbuf, (uint8_t *)&command_523_rsp, sizeof(hart_command_523_t)); req->rsp.len = sizeof(hart_command_523_t); update_compression_state_mapping_table(&map); uint8_t *p = &map.data[address]; if (address + count > ARRAY_LEN(map.data)) { count = ARRAY_LEN(map.data) - address; } osel_memcpy(req->rsp.pbuf + req->rsp.len, p, count); req->rsp.len += count; return TRUE; } // 524-扩展指令(写入压缩状态映射) static BOOL hart_write_compression_state_mapping_req(hart_user_req_t *const req) { return TRUE; } // 35-写入电流上下限(主变量范围) static BOOL hart_write_input_range_req(hart_command_req_t *const req) { float32_u tmp; tmp.f = req->data.command_35.pv_upper_range_value; tmp.c = B2S_UINT32(tmp.c); osel_memcpy((uint8_t *)&udevice.input_range_hi, (uint8_t *)&tmp.f, sizeof(float32)); tmp.f = req->data.command_35.pv_lower_range_value; tmp.c = B2S_UINT32(tmp.c); osel_memcpy((uint8_t *)&udevice.input_range_lo, (uint8_t *)&tmp.f, sizeof(float32)); return TRUE; } // 44-主变量单位 static BOOL hart_write_pv_unit_req(hart_command_req_t *const req) { hart_device_variable_t *variable = NULL; udevice.input_unit = req->data.command_44.pv_units_code; variable = get_device_variable_by_standard_code(DIN_246); variable->units_code = req->data.command_44.pv_units_code; return TRUE; } // 53-同步压力或者电流变量单位 static BOOL hart_write_variable_unit_req(hart_command_req_t *const req) { if (req->data.command_53.device_ariable == DEV_TEMPERATURE) ///< 将命令53修改的变量:温度同步到命令129的变量:温度单位 { udevice.temp_unit = req->data.command_53.device_ariable_unit_code; } else if (req->data.command_53.device_ariable == DEV_PRESS) ///< 将命令53修改的变量:压力同步到命令129的变量:压力单位 { udevice.press_unit = req->data.command_53.device_ariable_unit_code; } return TRUE; } // 131-写入整定参数 static BOOL hart_write_tuning_param_req(hart_user_req_t *const req) { hart_command_131_t *cmd = &req->data.command_131; if (cmd->tuning_type == 0x01) { // 位置整定参数 udevice.pos_tuning_set = cmd->tuning_data; } else if (cmd->tuning_type == 0x02) { // 压力整定参数 udevice.press_tuning_set = cmd->tuning_data; } else { return FALSE; } req->rsp.len = sizeof(hart_command_131_t); osel_memset((uint8_t *)&req->rsp.pbuf, 0, HART_RESPONSE_MAX_LEN); osel_memcpy(req->rsp.pbuf, (uint8_t *)cmd, req->rsp.len); return TRUE; } // 132-读取整定参数 static BOOL hart_read_tuning_param_req(hart_user_req_t *const req) { hart_command_132_t cmd; cmd.pos_tuning_set = udevice.pos_tuning_set; cmd.press_tuning_set = udevice.press_tuning_set; req->rsp.len = sizeof(hart_command_132_t); osel_memset((uint8_t *)&req->rsp.pbuf, 0, HART_RESPONSE_MAX_LEN); osel_memcpy(req->rsp.pbuf, (uint8_t *)&cmd, req->rsp.len); return TRUE; } // 164-读取规格表数据 static BOOL hart_read_specification_req(hart_user_req_t *const req) { uint8_t *address = &spec_table_data.ss2_ver; address += req->data.command_164.address; req->rsp.len = req->data.command_164.length; osel_memset((uint8_t *)&req->rsp.pbuf, 0, HART_RESPONSE_MAX_LEN); osel_memcpy(req->rsp.pbuf, address, req->rsp.len); return TRUE; } // 165-写入规格表数据 static BOOL hart_write_specification_req(hart_user_req_t *const req) { uint8_t length = req->data_length - 2; uint8_t *address = &spec_table_data.ss2_ver; address += req->data.command_165.address; if (req->data.command_165.address + length > sizeof(specification_table_data_t)) { return FALSE; } osel_memcpy(address, req->data.command_165.pbuf, length); // 回复数据 req->rsp.len = req->data_length; req->data.command_165.address = S2B_UINT16(req->data.command_165.address); osel_memset((uint8_t *)&req->rsp.pbuf, 0, HART_RESPONSE_MAX_LEN); osel_memcpy(req->rsp.pbuf, (uint8_t *)&req->data.command_165.address, sizeof(uint16_t)); osel_memcpy(req->rsp.pbuf + sizeof(uint16_t), address, length); spec_table_data_mapping(FALSE); // 规格表中的数据和udevice中的属性做映射关系 fal_execution_sem_update(); return TRUE; } /** * @brief 处理HART接口用户事件 * * 根据传入的事件和数据,执行相应的处理函数。 * * @param event HART接口用户事件 * @param data 事件相关数据 * * @return 处理结果,成功返回TRUE,失败返回FALSE */ BOOL hart_user_handle(hart_interface_user_event_e event, const void *const data) { BOOL ret = FALSE; switch (event) { case HART_COMMAND_35_EVENT: // 写入电流上下限(主变量范围) ret = hart_write_input_range_req((hart_command_req_t *)data); break; case HART_COMMAND_44_EVENT: // 写入主变量单位 ret = hart_write_pv_unit_req((hart_command_req_t *)data); break; case HART_COMMAND_53_EVENT: // 写入设备变量单位 ret = hart_write_variable_unit_req((hart_command_req_t *)data); break; case HART_COMMAND_109_EVENT: // 突发模式控制 ret = hart_burst_mode_control_req((hart_user_req_t *)data); break; case HART_COMMAND_131_EVENT: // 写入整定参数 ret = hart_write_tuning_param_req((hart_user_req_t *)data); break; case HART_COMMAND_132_EVENT: // 读取整定参数 ret = hart_read_tuning_param_req((hart_user_req_t *)data); break; case HART_COMMAND_133_EVENT: // 获取打开的文件信息 ret = hart_read_file_information_req((hart_user_req_t *)data); break; case HART_COMMAND_134_EVENT: // 读取文件 ret = hart_file_read_req((hart_user_req_t *)data); break; case HART_COMMAND_135_EVENT: // 写入文件 ret = hart_file_write_req((hart_user_req_t *)data); break; case HART_COMMAND_136_EVENT: // 读取/解除/写入EEPROM ret = hart_epprom_multiple_operations((hart_user_req_t *)data); break; case HART_COMMAND_138_EVENT: // 读取其他状态 ret = hart_read_other_status_req((hart_user_req_t *)data); break; case HART_COMMAND_140_EVENT: // 读取触发器定义的内容 ret = hart_read_trigger_definition_req((hart_user_req_t *)data); break; case HART_COMMAND_142_EVENT: // 执行校准 ret = hart_tuning_req((hart_user_req_t *)data); break; case HART_COMMAND_143_EVENT: // 设置阀门序列号 ret = hart_set_valve_sn_req((hart_user_req_t *)data); break; case HART_COMMAND_144_EVENT: // 读取阀门序列号 ret = hart_read_valve_sn_req((hart_user_req_t *)data); break; case HART_COMMAND_145_EVENT: // 读取仪器序列号 ret = hart_read_device_sn_req((hart_user_req_t *)data); break; case HART_COMMAND_146_EVENT: // 读取标准跨度信息 ret = hart_read_standard_span_req((hart_user_req_t *)data); break; case HART_COMMAND_147_EVENT: // 读取设备等级 ret = hart_read_device_level_req((hart_user_req_t *)data); break; case HART_COMMAND_149_EVENT: // 设置仪器时间 ret = hart_set_dev_time_req((hart_user_req_t *)data); break; case HART_COMMAND_150_EVENT: // 读取设备时间 ret = hart_read_dev_time_req((hart_user_req_t *)data); break; case HART_COMMAND_151_EVENT: // 读取版本 ret = hart_read_version_req((hart_user_req_t *)data); break; case HART_COMMAND_153_EVENT: // 读取校准记录 ret = hart_read_calibration_record_req((hart_user_req_t *)data); break; case HART_COMMAND_154_EVENT: // 设置仪器序列号 ret = hart_set_dev_sn_req((hart_user_req_t *)data); break; case HART_COMMAND_155_EVENT: // 执行诊断 ret = hart_mode_diagnosis_req((hart_user_req_t *)data); break; case HART_COMMAND_156_EVENT: // 读取诊断状态 ret = hart_read_diagnosis_state_req((hart_user_req_t *)data); break; case HART_COMMAND_157_EVENT: // 停止诊断 ret = hart_mode_diagnosis_stop_req(); break; case HART_COMMAND_158_EVENT: // 在线诊断测试 ret = hart_mode_diagnosis_test_req((hart_user_req_t *)data); break; case HART_COMMAND_162_EVENT: // 设置气源气压/A口/B口 ret = hart_set_pressure_req((hart_user_req_t *)data); break; case HART_COMMAND_164_EVENT: // 读取规格表数据 ret = hart_read_specification_req((hart_user_req_t *)data); break; case HART_COMMAND_165_EVENT: // 写入规格表数据 ret = hart_write_specification_req((hart_user_req_t *)data); break; case HART_COMMAND_167_EVENT: // 写入校准记录(操作日期和操作人员) ret = hart_set_calibration_record_req((hart_user_req_t *)data); break; case HART_COMMAND_168_EVENT: // 读取部分行程报警 ret = hart_read_partial_stroke_alarm_req((hart_user_req_t *)data); break; case HART_COMMAND_170_EVENT: // 读取制造信息序列号 ret = hart_read_manufacturing_sn_req((hart_user_req_t *)data); break; case HART_COMMAND_187_EVENT: // 测试指令 ret = hart_test_req((hart_user_req_t *)data); break; case HART_COMMAND_200_EVENT: // 读取NVM非易失性存储器数据 ret = hart_read_nvw_data_req((hart_user_req_t *)data); break; case HART_COMMAND_523_EVENT: // 读取压缩状态映射 ret = hart_read_compression_state_mapping_req((hart_user_req_t *)data); break; case HART_COMMAND_524_EVENT: // 写入压缩状态映射 ret = hart_write_compression_state_mapping_req((hart_user_req_t *)data); break; default: break; } return ret; }