#include "../inc/hart_master.h" #include "../inc/hart_master_req.h" static hart_master_init_t *handle; // 主机请求指令 /** * @brief hart主机请求指令不需要携带数据域 * @param {hart_command_req_data_u} *data: 请求指令数据 * @param {uint8_t} **resp: 待填充数据的区间,指针的指针 * @return: TRUE: 处理成功 * FALSE: 处理失败 */ BOOL hart_master_command_without_data_req(const hart_command_req_t *const req, hart_response_t *resp) { // 数据个数为0不需要填充数据域 return TRUE; } /** * @brief 写入轮训地址 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_6_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_6.poll_address; // 设备的轮询地址 if (hart_get_current_protocol_version() == HART_PROTOCOL_VERSION_7) { *resp->data_p++ = req->data.command_6.loop_current_mode; // 回路电流模式 } return TRUE; } /** * @brief 读取具有状态的设备变量 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_9_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = DIN_245; // slot0 *resp->data_p++ = DIN_246; // slot1 *resp->data_p++ = DIN_247; // slot2 *resp->data_p++ = DIN_248; // slot3 *resp->data_p++ = DIN_249; // slot4 *resp->data_p++ = DIN_250; // slot5 *resp->data_p++ = DIN_250; // slot6 *resp->data_p++ = DIN_250; // slot7 return TRUE; } /** * @brief 读取与标签关联的唯一标识符V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_11_req(const hart_command_req_t *const req, hart_response_t *resp) { for (uint8_t i = 0; i < HART_PACKED6_LEN; i++) { *resp->data_p++ = req->data.command_11.tag[i]; } return TRUE; } /** * @brief 写入消息V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_17_req(const hart_command_req_t *const req, hart_response_t *resp) { for (uint8_t i = 0; i < HART_PACKED24_LEN; i++) { *resp->data_p++ = req->data.command_17.message[i]; } return TRUE; } /** * @brief 写标签、描述符、日期 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_18_req(const hart_command_req_t *const req, hart_response_t *resp) { for (uint8_t i = 0; i < HART_PACKED6_LEN; i++) { *resp->data_p++ = req->data.command_18.tag[i]; } for (uint8_t i = 0; i < HART_PACKED12_LEN; i++) { *resp->data_p++ = req->data.command_18.descriptor[i]; } for (uint8_t i = 0; i < HART_DATE_LEN; i++) { *resp->data_p++ = req->data.command_18.date[i]; } return TRUE; } /** * @brief 编写总装编号 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_19_req(const hart_command_req_t *const req, hart_response_t *resp) { osel_memcpy(resp->data_p, req->data.command_19.final_assembly_number, HART_PACKED3_LEN); resp->data_p += HART_PACKED3_LEN; return TRUE; } /** * @brief 读取与长标签关联的唯一标识符 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_21_req(const hart_command_req_t *const req, hart_response_t *resp) { for (uint8_t i = 0; i < HART_PACKED32_LEN; i++) { *resp->data_p++ = req->data.command_21.long_tag[i]; } return TRUE; } /** * @brief 写长标签 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_22_req(const hart_command_req_t *const req, hart_response_t *resp) { for (uint8_t i = 0; i < HART_PACKED32_LEN; i++) { *resp->data_p++ = req->data.command_22.long_tag[i]; } return TRUE; } /** * @brief 重置配置更改标志 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_38_req(const hart_command_req_t *const req, hart_response_t *resp) { uint16_t configuration_change_counter = req->data.command_38.configuration_change_counter; configuration_change_counter = B2S_UINT16(configuration_change_counter); osel_memcpy(resp->data_p, (uint8_t *)&configuration_change_counter, sizeof(uint16_t)); resp->data_p += sizeof(uint16_t); return TRUE; } /** * @brief 读取设备变量V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_33_req(const hart_command_req_t *const req, hart_response_t *resp) { osel_memcpy(resp->data_p, (uint8_t *)&req->data.command_33, sizeof(hart_command_33_t)); resp->data_p += sizeof(hart_command_33_t); return TRUE; } /** * @brief 写入主变量阻尼值V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_34_req(const hart_command_req_t *const req, hart_response_t *resp) { float32_u tmp; tmp.f = req->data.command_34.pv_damping_value; tmp.c = S2B_UINT32(tmp.c); osel_memcpy(resp->data_p, (uint8_t *)&tmp, sizeof(float32_u)); resp->data_p += sizeof(float32_u); return TRUE; } /** * @brief 写入主变量范围值V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_35_req(const hart_command_req_t *const req, hart_response_t *resp) { float32_u tmp; *resp->data_p++ = req->data.command_35.pv_upper_and_lower_range_values_units_code; tmp.f = req->data.command_35.pv_upper_range_value; tmp.c = S2B_UINT32(tmp.c); osel_memcpy(resp->data_p, (uint8_t *)&tmp, sizeof(float32_u)); resp->data_p += sizeof(float32_u); tmp.f = req->data.command_35.pv_lower_range_value; tmp.c = S2B_UINT32(tmp.c); osel_memcpy(resp->data_p, (uint8_t *)&tmp, sizeof(float32_u)); resp->data_p += sizeof(float32_u); return TRUE; } /** * @brief EEPROM控制V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_39_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_39.control_code; return TRUE; } /** * @brief 进入/退出固定电流模式V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_40_req(const hart_command_req_t *const req, hart_response_t *resp) { float32_u tmp; tmp.f = req->data.command_40.pv_fixed_current_level; tmp.c = S2B_UINT32(tmp.c); osel_memcpy(resp->data_p, (uint8_t *)&tmp, sizeof(float32_u)); resp->data_p += sizeof(float32_u); return TRUE; } /** * @brief 编写主变量单元V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_44_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_44.pv_units_code; return TRUE; } /** * @brief 微调回路电流归零 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_45_req(const hart_command_req_t *const req, hart_response_t *resp) { float32_u tmp; tmp.f = req->data.command_45.pv_loop_current_level; tmp.c = S2B_UINT32(tmp.c); osel_memcpy(resp->data_p, (uint8_t *)&tmp, sizeof(float32_u)); resp->data_p += sizeof(float32_u); return TRUE; } /** * @brief 微调回路电流增益 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_46_req(const hart_command_req_t *const req, hart_response_t *resp) { float32_u tmp; tmp.f = req->data.command_46.pv_loop_current_level; tmp.c = S2B_UINT32(tmp.c); osel_memcpy(resp->data_p, (uint8_t *)&tmp, sizeof(float32_u)); resp->data_p += sizeof(float32_u); return TRUE; } /** * @brief 编写主变量传递函数V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_47_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_47.pv_transfer_function_code; return TRUE; } /** * @brief 写入主变量传感器序列号V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_49_req(const hart_command_req_t *const req, hart_response_t *resp) { osel_memcpy(resp->data_p, req->data.command_49.pv_transducer_serial_number.bs, sizeof(uint24_t)); resp->data_p += sizeof(uint24_t); return TRUE; } /** * @brief 编写动态变量赋值V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_51_req(const hart_command_req_t *const req, hart_response_t *resp) { for (uint8_t i = 0; i < ARRAY_LEN(req->data.command_51.device_ariables); i++) { *resp->data_p++ = req->data.command_51.device_ariables[i]; } return TRUE; } /** * @brief 设置设备变量零V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_52_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_52.device_ariable; return TRUE; } /** * @brief 写入设备变量单位V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_53_req(const hart_command_req_t *const req, hart_response_t *resp) { osel_memcpy(resp->data_p, (uint8_t *)&req->data.command_53.device_ariable, sizeof(hart_command_53_t)); resp->data_p += sizeof(hart_command_53_t); return TRUE; } /** * @brief 读取设备变量信息V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_54_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_54.device_ariable; return TRUE; } /** * @brief 写入设备可变阻尼值V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_55_req(const hart_command_req_t *const req, hart_response_t *resp) { float32_u tmp; *resp->data_p++ = req->data.command_55.device_ariable; tmp.f = req->data.command_55.damping_value; tmp.c = S2B_UINT32(tmp.c); osel_memcpy(resp->data_p, (uint8_t *)&tmp, sizeof(float32_u)); // 设备可变阻尼值 resp->data_p += sizeof(float32_u); return TRUE; } /** * @brief 写入设备可变传感器序列号V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_56_req(const hart_command_req_t *const req, hart_response_t *resp) { osel_memcpy(resp->data_p, (uint8_t *)&req->data.command_56, sizeof(hart_command_56_t)); resp->data_p += sizeof(hart_command_56_t); return TRUE; } /** * @brief 编写单位标签、描述符、日期V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_58_req(const hart_command_req_t *const req, hart_response_t *resp) { osel_memcpy(resp->data_p, (uint8_t *)&req->data.command_58, sizeof(hart_command_58_t)); resp->data_p += sizeof(hart_command_58_t); return TRUE; } /** * @brief 写入响应序码数V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_59_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_59.s2m_preambles; return TRUE; } /** * @brief读取模拟通道和范围百分比V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_60_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_60.analog_channel_number_code; return TRUE; } /** * @brief 读取模拟通道V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_62_req(const hart_command_req_t *const req, hart_response_t *resp) { osel_memcpy(resp->data_p, (uint8_t *)&req->data.command_62, sizeof(hart_command_62_t)); resp->data_p += sizeof(hart_command_62_t); return TRUE; } /** * @brief 读取模拟通道信息V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_63_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_63.analog_channel_number_code; return TRUE; } /** * @brief 写入模拟通道附加阻尼值V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_64_req(const hart_command_req_t *const req, hart_response_t *resp) { float32_u tmp; *resp->data_p++ = req->data.command_64.analog_channel_number_code; tmp.f = req->data.command_64.damping_value; tmp.c = S2B_UINT32(tmp.c); osel_memcpy(resp->data_p, (uint8_t *)&tmp, sizeof(float32_u)); // 模拟通道附加阻尼值 resp->data_p += sizeof(float32_u); return TRUE; } /** * @brief 写入模拟通道范围值V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_65_req(const hart_command_req_t *const req, hart_response_t *resp) { float32_u tmp; *resp->data_p++ = req->data.command_65.analog_channel_number_code; *resp->data_p++ = req->data.command_65.upper_and_lower_range_values_units_code; tmp.f = req->data.command_65.upper_range_value; tmp.c = S2B_UINT32(tmp.c); osel_memcpy(resp->data_p, (uint8_t *)&tmp, sizeof(float32_u)); // 模拟通道上限值 resp->data_p += sizeof(float32_u); tmp.f = req->data.command_65.lower_range_value; tmp.c = S2B_UINT32(tmp.c); osel_memcpy(resp->data_p, (uint8_t *)&tmp, sizeof(float32_u)); // 模拟通道下限值 resp->data_p += sizeof(float32_u); return TRUE; } /** * @brief 进入/退出固定模拟通道模式V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_66_req(const hart_command_req_t *const req, hart_response_t *resp) { float32_u tmp; *resp->data_p++ = req->data.command_66.analog_channel_number_code; *resp->data_p++ = req->data.command_66.units_code; osel_memcpy((uint8_t *)&tmp.c, (uint8_t *)&req->data.command_66.fixed_analog_channel_level, sizeof(int32_t)); tmp.c = S2B_UINT32(tmp.c); osel_memcpy(resp->data_p, (uint8_t *)&tmp, sizeof(float32_u)); resp->data_p += sizeof(float32_u); return TRUE; } /** * @brief 调整模拟通道零V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_67_req(const hart_command_req_t *const req, hart_response_t *resp) { float32_u tmp; *resp->data_p++ = req->data.command_67.analog_channel_number_code; *resp->data_p++ = req->data.command_67.units_code; osel_memcpy((uint8_t *)&tmp.c, (uint8_t *)&req->data.command_67.actual_analog_channel_level, sizeof(int32_t)); tmp.c = S2B_UINT32(tmp.c); osel_memcpy(resp->data_p, (uint8_t *)&tmp, sizeof(float32_u)); resp->data_p += sizeof(float32_u); return TRUE; } /** * @brief 微调模拟通道增益V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_68_req(const hart_command_req_t *const req, hart_response_t *resp) { float32_u tmp; *resp->data_p++ = req->data.command_68.analog_channel_number_code; *resp->data_p++ = req->data.command_68.units_code; osel_memcpy((uint8_t *)&tmp.c, (uint8_t *)&req->data.command_68.externally_measured_analog_channel_level, sizeof(int32_t)); tmp.c = S2B_UINT32(tmp.c); osel_memcpy(resp->data_p, (uint8_t *)&tmp, sizeof(float32_u)); resp->data_p += sizeof(float32_u); return TRUE; } /** * @brief 写入模拟通道传递函数V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_69_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_69.analog_channel_number_code; *resp->data_p++ = req->data.command_69.transfer_function_code; return TRUE; } /** * @brief 读取模拟通道端点值V5 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_70_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_70.analog_channel_number_code; return TRUE; } /** * @brief 锁定装置 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_71_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_71.lock_code; return TRUE; } /** * @brief 呼叫 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_72_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_72.squawk_control_code; return TRUE; } /** * @brief 读取I/O系统功能 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_74_req(const hart_command_req_t *const req, hart_response_t *resp) { // 判断是否是广播地址 if (!is_broadcast_address((uint8_t *)&req->address, HART_LONG_ADDRESS_LEN)) { return FALSE; } return TRUE; } /** * @brief 轮询子设备 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_75_req(const hart_command_req_t *const req, hart_response_t *resp) { if (!is_broadcast_address((uint8_t *)&req->address, HART_LONG_ADDRESS_LEN)) { return FALSE; } *resp->data_p++ = req->data.command_75.card; *resp->data_p++ = req->data.command_75.channel; *resp->data_p++ = req->data.command_75.poll_address; return TRUE; } /** * @brief 向子设备发送命令 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_77_req(const hart_command_req_t *const req, hart_response_t *resp) { return TRUE; } BOOL hart_master_command_78_req(const hart_command_req_t *const req, hart_response_t *resp) { return TRUE; } /** * @brief 写入设备变量 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_79_req(const hart_command_req_t *const req, hart_response_t *resp) { float32_u tmp; *resp->data_p++ = req->data.command_79.device_ariable; *resp->data_p++ = req->data.command_79.device_ariable_command_code; *resp->data_p++ = req->data.command_79.device_ariable_unit_code; tmp.f = req->data.command_79.device_ariable_value; tmp.c = S2B_UINT32(tmp.c); osel_memcpy(resp->data_p, (uint8_t *)&tmp, sizeof(float32_u)); resp->data_p += sizeof(float32_u); *resp->data_p++ = req->data.command_79.status; return TRUE; } /** * @brief 读取设备可变微调点 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_80_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_80.device_ariable; return TRUE; } /** * @brief 读取设备变量调整指南 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_81_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_81.device_ariable; return TRUE; } /** * @brief 写入设备可变微调点 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_82_req(const hart_command_req_t *const req, hart_response_t *resp) { float32_u tmp; *resp->data_p++ = req->data.command_82.device_ariable; *resp->data_p++ = req->data.command_82.trim_points; *resp->data_p++ = req->data.command_82.units_code; tmp.f = req->data.command_82.value; tmp.c = S2B_UINT32(tmp.c); osel_memcpy(resp->data_p, (uint8_t *)&tmp, sizeof(float32_u)); resp->data_p += sizeof(float32_u); return TRUE; } /** * @brief 重置设备变量调整 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_83_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_83.device_ariable; return TRUE; } /** * @brief 读取子设备标识摘要 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_84_req(const hart_command_req_t *const req, hart_response_t *resp) { // 判断是否是广播地址 if (!is_broadcast_address((uint8_t *)&req->address, HART_LONG_ADDRESS_LEN)) { return FALSE; } *resp->data_p++ = HI_UINT16(req->data.command_84.identifier); *resp->data_p++ = LO_UINT16(req->data.command_84.identifier); return TRUE; } /** * @brief 读取I/O通道统计信息 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_85_req(const hart_command_req_t *const req, hart_response_t *resp) { // 判断是否是广播地址 if (!is_broadcast_address((uint8_t *)&req->address, HART_LONG_ADDRESS_LEN)) { return FALSE; } *resp->data_p++ = req->data.command_85.card; *resp->data_p++ = req->data.command_85.channel; return TRUE; } /** * @brief 读取子设备统计信息 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_86_req(const hart_command_req_t *const req, hart_response_t *resp) { // 判断是否是广播地址 if (!is_broadcast_address((uint8_t *)&req->address, HART_LONG_ADDRESS_LEN)) { return FALSE; } *resp->data_p++ = HI_UINT16(req->data.command_86.identifier); *resp->data_p++ = LO_UINT16(req->data.command_86.identifier); return TRUE; } /** * @brief 写入I/O系统主模式 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_87_req(const hart_command_req_t *const req, hart_response_t *resp) { // 判断是否是广播地址 if (!is_broadcast_address((uint8_t *)&req->address, HART_LONG_ADDRESS_LEN)) { return FALSE; } *resp->data_p++ = req->data.command_87.master_mode; return TRUE; } /** * @brief 写入I/O系统重试计数 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_88_req(const hart_command_req_t *const req, hart_response_t *resp) { // 判断是否是广播地址 if (!is_broadcast_address((uint8_t *)&req->address, HART_LONG_ADDRESS_LEN)) { return FALSE; } *resp->data_p++ = req->data.command_88.retry_count; return TRUE; } /** * @brief 设置实时时钟 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_89_req(const hart_command_req_t *const req, hart_response_t *resp) { uint32_t time = 0; *resp->data_p++ = req->data.command_89.time_set_code; osel_memcpy(resp->data_p, (uint8_t *)&req->data.command_89.date, HART_DATE_LEN); resp->data_p += HART_DATE_LEN; time = S2B_UINT32(req->data.command_89.time); osel_memcpy(resp->data_p, (uint8_t *)&time, sizeof(uint32_t)); resp->data_p += sizeof(uint32_t); *resp->data_p++ = HI_UINT16(req->data.command_89.transmission_time); *resp->data_p++ = LO_UINT16(req->data.command_89.transmission_time); return TRUE; } /** * @brief 读取趋势配置 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_91_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_91.trend_number; return TRUE; } /** * @brief 写入趋势配置 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_92_req(const hart_command_req_t *const req, hart_response_t *resp) { uint32_t time = 0; *resp->data_p++ = req->data.command_92.trend_number; *resp->data_p++ = req->data.command_92.trend_code; *resp->data_p++ = req->data.command_92.device_variable_code; time = req->data.command_92.trend_sample_interval; time = S2B_UINT32(time); osel_memcpy(resp->data_p, (uint8_t *)&time, sizeof(uint32_t)); resp->data_p += sizeof(uint32_t); return TRUE; } /** * @brief 读取趋势 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_93_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_93.trend_number; return TRUE; } /** * @brief 读取同步操作 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_96_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_96.action_number; return TRUE; } BOOL hart_master_command_97_req(const hart_command_req_t *const req, hart_response_t *resp) { uint32_t time = 0; *resp->data_p++ = req->data.command_97.action_number; // 动作号 *resp->data_p++ = req->data.command_97.action_control_code; // 动作控制码 *resp->data_p++ = req->data.command_97.device_variable_code; // 设备变量代码 *resp->data_p++ = HI_UINT16(req->data.command_97.command_number); // 命令号 *resp->data_p++ = LO_UINT16(req->data.command_97.command_number); osel_memcpy(resp->data_p, (uint8_t *)&req->data.command_97.trigger_date, HART_DATE_LEN); // 命令数据 resp->data_p += HART_DATE_LEN; time = S2B_UINT32(req->data.command_97.trigger_time); osel_memcpy(resp->data_p, (uint8_t *)&time, sizeof(uint32_t)); resp->data_p += sizeof(uint32_t); return TRUE; } /** * @brief读取命令操作 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_98_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_98.action_number; return TRUE; } /** * @brief 配置命令操作 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_99_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_99.action_number; *resp->data_p++ = HI_UINT16(req->data.command_99.command_number); // 命令号 *resp->data_p++ = LO_UINT16(req->data.command_99.command_number); *resp->data_p++ = req->data.command_99.command_data_length; osel_memcpy(resp->data_p, (uint8_t *)req->data.command_99.command_data, req->data.command_99.command_data_length); resp->data_p += req->data.command_99.command_data_length; return TRUE; } /** * @brief 写入主变量报警码 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_100_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_100.pv_alarm_selection_code; return TRUE; } /** * @brief 读取子设备到突发消息映射 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_101_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_101.burst_message; return TRUE; } /** * @brief将子设备映射到突发信息 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_102_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_102.burst_message; *resp->data_p++ = HI_UINT16(req->data.command_102.sub_device_index); *resp->data_p++ = LO_UINT16(req->data.command_102.sub_device_index); return TRUE; } /** * @brief 写入突发周期 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_103_req(const hart_command_req_t *const req, hart_response_t *resp) { uint32_t time = 0; *resp->data_p++ = req->data.command_103.burst_message; time = S2B_UINT32(req->data.command_103.update_period_time); osel_memcpy(resp->data_p, (uint8_t *)&time, sizeof(uint32_t)); resp->data_p += sizeof(uint32_t); time = S2B_UINT32(req->data.command_103.max_update_period_time); osel_memcpy(resp->data_p, (uint8_t *)&time, sizeof(uint32_t)); resp->data_p += sizeof(uint32_t); return TRUE; } /** * @brief 写入突发触发器 * @param {hart_command_req_t} *req * @param {hart_response_t} *resp * @return {*} */ BOOL hart_master_command_104_req(const hart_command_req_t *const req, hart_response_t *resp) { float32_u f; f.f = req->data.command_104.trigger_level; f.c = S2B_UINT32(f.c); *resp->data_p++ = req->data.command_104.burst_message; // 突发消息编号 *resp->data_p++ = req->data.command_104.burst_message_trigger_code; // 突发触发器代码 *resp->data_p++ = req->data.command_104.device_variable_vlassification_for_trigger_level; // 触发器级别的设备变量分类 *resp->data_p++ = req->data.command_104.units_code; // 突发触发器单位代码 osel_memcpy(resp->data_p, (uint8_t *)&f, sizeof(float32_u)); // 触发电平 resp->data_p += sizeof(float32_u); return TRUE; } BOOL hart_master_command_105_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = req->data.command_105.burst_message; return TRUE; } BOOL hart_master_command_107_req(const hart_command_req_t *const req, hart_response_t *resp) { osel_memcpy(resp->data_p, (uint8_t *)&req->data.command_107, sizeof(hart_command_107_t)); resp->data_p += sizeof(hart_command_107_t); return TRUE; } BOOL hart_master_command_513_req(const hart_command_req_t *const req, hart_response_t *resp) { *resp->data_p++ = HI_UINT16(req->data.command_513.country_code); *resp->data_p++ = LO_UINT16(req->data.command_513.country_code); *resp->data_p++ = req->data.command_513.si_units_control_code; return TRUE; } // 结束:主机请求指令 /** * @brief 主机请求指令接口 * @param {hart_command_req_t} *req: 请求参数 * @return: TRUE: 请求成功 * FALSE: 请求失败 */ BOOL hart_master_command_req(const hart_command_req_t *const req) { uint8_t rsp_len = 0; // 响应数据长度 uint8_t xor = 0; // 异或校验 uint8_t preamble_def = HART_PREAMBLE_DEFAULT_LEN; // 引导码默认长度 hart_delimiter_u delimiter; // 界定符 hart_short_address_u poll_address; hart_long_address_u long_address; uint8_t *data_len_p = NULL; // 数据长度指针 handle->response->data_length = 0; handle->response->data_p = handle->response->data; osel_memset((uint8_t *)handle->response->data, 0, HART_RESPONSE_MAX_LEN); delimiter.data = 0; osel_memset(&poll_address.data, 0, HART_SHORT_ADDRESS_LEN); osel_memset((uint8_t *)&long_address.data, 0, HART_LONG_ADDRESS_LEN); // 检查参数 if (!DBG_ASSERT(handle->response_call != NULL __DBG_LINE)) return FALSE; // 检查请求命令 if (req->command > HART_COMMAND_MAX) return FALSE; if (FALSE == hart_is_support_command(req->command)) // 当前模式使用的版本号,请求命令是否支持 return FALSE; // 检查界定符和命令关系: HART协议规定只有0号通用命令支持短帧格式,其他命令发送之前通过发送命令0获取设备长地址,除非使用长地址发送命令 if (req->command > HART_COMMAND_0) { if (!DBG_ASSERT(req->delimiter_type != HART_DELIMITER_TYPE_SHORT __DBG_LINE)) // 除命令0以外的数据帧都是长帧格式 return FALSE; } // 填充请求数据 // 填充引导码 if (req->delimiter_type == HART_DELIMITER_TYPE_SHORT && req->command == HART_COMMAND_0) { // 一般是5-20个0xFF, 它是一组同步传输的同步信号, 用以保证信息的同步。在开始通讯的时候,使用的是20个FF引导码,用以保证通讯的同步。 preamble_def = 20; } for (uint8_t i = 0; i < preamble_def; i++) { *handle->response->data_p++ = HART_PREAMBLE; } // 填充界定符。如果命令大于0xFF,填充界定符中的扩展字节数量 delimiter.bits.frame_type = HART_STX_FRAME; delimiter.bits.addr_type = req->delimiter_type; if (req->command < 0xFF) { delimiter.bits.ext_bytes = 0; } else { delimiter.bits.ext_bytes = 1; } *handle->response->data_p++ = delimiter.data; // 填充地址 if (req->delimiter_type == HART_DELIMITER_TYPE_SHORT) { poll_address.bits.master = handle->address_bit; poll_address.bits.slave = req->address[0]; *handle->response->data_p++ = poll_address.data; } else { long_address.bits.master = handle->address_bit; long_address.bits.reserved = req->address[0]; // long_address.data.bs[0] = req->address[0]; osel_memcpy((uint8_t *)&long_address.bits.slave, &req->address[1], HART_LONG_ADDRESS_LEN - 1); osel_memcpy(handle->response->data_p, (uint8_t *)&long_address.data, HART_LONG_ADDRESS_LEN); // 长地址5个字节 handle->response->data_p += HART_LONG_ADDRESS_LEN; } // 填充命令 if (delimiter.bits.ext_bytes == 0) { *handle->response->data_p++ = req->command; } else { // 目前为止扩展字节只有1个,所以只考虑1个的情况 uint16_t command = (uint16_t)(req->command); *handle->response->data_p++ = HI_UINT16(command); *handle->response->data_p++ = LO_UINT16(command); } if (hart_command_ptr_arr[req->command] != NULL) { // 检查数据域,并填充数据长度和数据 data_len_p = handle->response->data_p; hart_frame_data_length_start(&data_len_p); handle->response->data_p++; if (!hart_command_ptr_arr[req->command](req, handle->response)) { // TODO return FALSE; } else { hart_frame_data_length_end(handle->response->data_p); // 填充校验码 rsp_len = handle->response->data_p - handle->response->data; xor = xor_compute(&handle->response->data[preamble_def], (rsp_len - preamble_def)); // 除前导码和校验字节外所有字节的异或之后 *handle->response->data_p++ = xor; rsp_len++; handle->response->data_length = rsp_len; if (handle->response->data_length > 0) { handle->response_call(0, handle->response->data, handle->response->data_length); } return TRUE; } } else { return FALSE; } } BOOL hart_master_req_init(const hart_master_init_t *const init) { if (!DBG_ASSERT(init != NULL __DBG_LINE)) return FALSE; handle = (hart_master_init_t *)init; // 初始化指令处理函数,指向hart_master_command_without_data_req,不需要携带数据域 for (uint16_t i = 0; i < HART_COMMAND_MAX; i++) { hart_command_ptr_arr[i] = hart_master_command_without_data_req; } // 需要携带数据域的指令处理函数,指向对应的处理函数 hart_command_ptr_arr[HART_COMMAND_6] = hart_master_command_6_req; hart_command_ptr_arr[HART_COMMAND_9] = hart_master_command_9_req; hart_command_ptr_arr[HART_COMMAND_11] = hart_master_command_11_req; hart_command_ptr_arr[HART_COMMAND_17] = hart_master_command_17_req; hart_command_ptr_arr[HART_COMMAND_18] = hart_master_command_18_req; hart_command_ptr_arr[HART_COMMAND_19] = hart_master_command_19_req; hart_command_ptr_arr[HART_COMMAND_21] = hart_master_command_21_req; hart_command_ptr_arr[HART_COMMAND_22] = hart_master_command_22_req; hart_command_ptr_arr[HART_COMMAND_38] = hart_master_command_38_req; hart_command_ptr_arr[HART_COMMAND_33] = hart_master_command_33_req; hart_command_ptr_arr[HART_COMMAND_34] = hart_master_command_34_req; hart_command_ptr_arr[HART_COMMAND_35] = hart_master_command_35_req; hart_command_ptr_arr[HART_COMMAND_39] = hart_master_command_39_req; hart_command_ptr_arr[HART_COMMAND_40] = hart_master_command_40_req; hart_command_ptr_arr[HART_COMMAND_44] = hart_master_command_44_req; hart_command_ptr_arr[HART_COMMAND_45] = hart_master_command_45_req; hart_command_ptr_arr[HART_COMMAND_46] = hart_master_command_46_req; hart_command_ptr_arr[HART_COMMAND_47] = hart_master_command_47_req; hart_command_ptr_arr[HART_COMMAND_49] = hart_master_command_49_req; hart_command_ptr_arr[HART_COMMAND_51] = hart_master_command_51_req; hart_command_ptr_arr[HART_COMMAND_52] = hart_master_command_52_req; hart_command_ptr_arr[HART_COMMAND_53] = hart_master_command_53_req; hart_command_ptr_arr[HART_COMMAND_54] = hart_master_command_54_req; hart_command_ptr_arr[HART_COMMAND_55] = hart_master_command_55_req; hart_command_ptr_arr[HART_COMMAND_56] = hart_master_command_56_req; hart_command_ptr_arr[HART_COMMAND_58] = hart_master_command_58_req; hart_command_ptr_arr[HART_COMMAND_59] = hart_master_command_59_req; hart_command_ptr_arr[HART_COMMAND_60] = hart_master_command_60_req; hart_command_ptr_arr[HART_COMMAND_62] = hart_master_command_62_req; hart_command_ptr_arr[HART_COMMAND_63] = hart_master_command_63_req; hart_command_ptr_arr[HART_COMMAND_64] = hart_master_command_64_req; hart_command_ptr_arr[HART_COMMAND_65] = hart_master_command_65_req; hart_command_ptr_arr[HART_COMMAND_66] = hart_master_command_66_req; hart_command_ptr_arr[HART_COMMAND_67] = hart_master_command_67_req; hart_command_ptr_arr[HART_COMMAND_68] = hart_master_command_68_req; hart_command_ptr_arr[HART_COMMAND_69] = hart_master_command_69_req; hart_command_ptr_arr[HART_COMMAND_70] = hart_master_command_70_req; hart_command_ptr_arr[HART_COMMAND_71] = hart_master_command_71_req; hart_command_ptr_arr[HART_COMMAND_72] = hart_master_command_72_req; hart_command_ptr_arr[HART_COMMAND_74] = hart_master_command_74_req; hart_command_ptr_arr[HART_COMMAND_75] = hart_master_command_75_req; hart_command_ptr_arr[HART_COMMAND_77] = hart_master_command_77_req; hart_command_ptr_arr[HART_COMMAND_78] = hart_master_command_78_req; hart_command_ptr_arr[HART_COMMAND_79] = hart_master_command_79_req; hart_command_ptr_arr[HART_COMMAND_80] = hart_master_command_80_req; hart_command_ptr_arr[HART_COMMAND_81] = hart_master_command_81_req; hart_command_ptr_arr[HART_COMMAND_82] = hart_master_command_82_req; hart_command_ptr_arr[HART_COMMAND_83] = hart_master_command_83_req; hart_command_ptr_arr[HART_COMMAND_84] = hart_master_command_84_req; hart_command_ptr_arr[HART_COMMAND_85] = hart_master_command_85_req; hart_command_ptr_arr[HART_COMMAND_86] = hart_master_command_86_req; hart_command_ptr_arr[HART_COMMAND_87] = hart_master_command_87_req; hart_command_ptr_arr[HART_COMMAND_88] = hart_master_command_88_req; hart_command_ptr_arr[HART_COMMAND_89] = hart_master_command_89_req; hart_command_ptr_arr[HART_COMMAND_91] = hart_master_command_91_req; hart_command_ptr_arr[HART_COMMAND_92] = hart_master_command_92_req; hart_command_ptr_arr[HART_COMMAND_93] = hart_master_command_93_req; hart_command_ptr_arr[HART_COMMAND_96] = hart_master_command_96_req; hart_command_ptr_arr[HART_COMMAND_97] = hart_master_command_97_req; hart_command_ptr_arr[HART_COMMAND_98] = hart_master_command_98_req; hart_command_ptr_arr[HART_COMMAND_99] = hart_master_command_99_req; hart_command_ptr_arr[HART_COMMAND_100] = hart_master_command_100_req; hart_command_ptr_arr[HART_COMMAND_101] = hart_master_command_101_req; hart_command_ptr_arr[HART_COMMAND_102] = hart_master_command_102_req; hart_command_ptr_arr[HART_COMMAND_103] = hart_master_command_103_req; hart_command_ptr_arr[HART_COMMAND_104] = hart_master_command_104_req; hart_command_ptr_arr[HART_COMMAND_105] = hart_master_command_105_req; hart_command_ptr_arr[HART_COMMAND_107] = hart_master_command_107_req; hart_command_ptr_arr[HART_COMMAND_513] = hart_master_command_513_req; hart_master_req_init_user(); return TRUE; }