This repository has been archived on 2025-02-28. You can view files and clone it, but cannot push or open issues or pull requests.
controller-hd/User/app_hart_user.c

1067 lines
37 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}