/* * @Author: * @Date: 2023-03-20 19:27:47 * @LastEditors: wangxujie-laptop 390834610@qq.com * @LastEditTime: 2024-09-11 10:51:36 * @FilePath: \hart\hart\hart_frame.c * @Description: * email: * Copyright (c) 2023 by xxx, All Rights Reserved. */ #include "./inc/hart_frame.h" #include "../slave/inc/hart_slave_frame.h" static uint8_t *hart_frame_data_length_p; // 帧数据长度位置 static uint8_t *hart_frame_response_code_p; // 帧响应码位置 /** * @brief 在处理请求开始时记录帧响应码起始位置 * @param {uint8_t} * * @return {*} */ void hart_frame_response_code_start(uint8_t **data_p) { hart_frame_response_code_p = *data_p; } /** * @brief 响应码第一个字节为通信有关的信息 * @param {uint8_t} code * @return {*} * 1. 第7位如果是1,则剩余的位包含了有关通信错误的信息 response_error_communication_code_e * 2. 第7位如果是0,则剩余的位包含了有关通信正常的信息 response_communication_code_e */ void hart_frame_response_communication_code(uint8_t code) { *hart_frame_response_code_p = code; } /** * @brief 响应码第二个字节为设备的操作状态有关的信息 * 如在第一个字节中最高位置1,则该字节无意义 * @param {uint8_t} code * @return {*} */ void hart_frame_slave_response_operate_code(hart_device_attribute_t *hart_device_attribute) { /** * 判断当前设备状态的crc和device_status_crc是否一致 * Note: Masters will issue this command whenever More Status Available (Bit 4 of the device status byte) issetAs a result, the Field Device must carefully define and contro the events and status information inthis command that affect these two device status bits. f the More Status Available bit is alwaysasserted. then communication bandwidth is effectively cut in half. */ // uint16_t crc = crc16_compute((uint8_t *)&hart_device_attribute->device_status.additional_device_status, sizeof(additional_device_status_t)); // if (hart_device_attribute->device_status.additional_device_status_crc != crc) // { // hart_device_status_set_operational_state(DEVICE_OPERATIONAL_STATE_5); // } // else // { // hart_device_status_clr_operational_state(DEVICE_OPERATIONAL_STATE_5); // } *(hart_frame_response_code_p + 1) = hart_device_attribute->device_status.operational_state; } /** * @brief 响应码第二个字节为设备的操作状态有关的信息,主机默认回复0x00 * @return {*} */ void hart_frame_master_response_operate_code(void) { *(hart_frame_response_code_p + 1) = 0x00; } /** * @brief在处理请求开始时记录帧数据域长度起始位置 * @param {uint8_t} *data_p * @return {*} */ void hart_frame_data_length_start(uint8_t **data_p) { DBG_ASSERT(data_p != NULL __DBG_LINE); DBG_ASSERT(*data_p != NULL __DBG_LINE); hart_frame_data_length_p = *data_p; } /** * @brief在处理请求结束时记录帧数据长度位置 * @param {uint8_t} *data_p * @return {*} */ void hart_frame_data_length_end(uint8_t *data_p) { *hart_frame_data_length_p = data_p - hart_frame_data_length_p - 1; // 计算数据个数 // LOG_PRINT("%d", *hart_frame_data_length_p); } // 判断指令是否是写 BOOL hart_is_write_command(uint16_t command) { // 先判断是否在用户自定义的指令中 uint16_t user_version[] = {HART_COMMAND_130, HART_COMMAND_131, HART_COMMAND_135, HART_COMMAND_143, HART_COMMAND_149, HART_COMMAND_154, HART_COMMAND_162, HART_COMMAND_165, HART_COMMAND_167}; if (is_in_array(user_version, ARRAY_LEN(user_version), command)) { return TRUE; } uint16_t cmd[] = {HART_COMMAND_6, HART_COMMAND_17, HART_COMMAND_18, HART_COMMAND_19, HART_COMMAND_22, /* HART_COMMAND_38,//ZKBW*/ HART_COMMAND_34, HART_COMMAND_35, HART_COMMAND_36, HART_COMMAND_37, HART_COMMAND_39, HART_COMMAND_40, HART_COMMAND_43, HART_COMMAND_44, HART_COMMAND_45, HART_COMMAND_46, HART_COMMAND_47, HART_COMMAND_49, HART_COMMAND_51, HART_COMMAND_52, HART_COMMAND_53, HART_COMMAND_55, HART_COMMAND_56, HART_COMMAND_58, HART_COMMAND_59, HART_COMMAND_64, HART_COMMAND_65, HART_COMMAND_66, HART_COMMAND_67, HART_COMMAND_68, HART_COMMAND_69, HART_COMMAND_79, HART_COMMAND_82, HART_COMMAND_83, HART_COMMAND_87, HART_COMMAND_88, HART_COMMAND_92, HART_COMMAND_97, HART_COMMAND_99, HART_COMMAND_100, HART_COMMAND_102, HART_COMMAND_103, HART_COMMAND_104, HART_COMMAND_107, HART_COMMAND_108, HART_COMMAND_109, HART_COMMAND_112, HART_COMMAND_116, HART_COMMAND_117, HART_COMMAND_118, HART_COMMAND_513, HART_COMMAND_517, HART_COMMAND_519, HART_COMMAND_521, HART_COMMAND_522, HART_COMMAND_524, HART_COMMAND_525, HART_COMMAND_526, HART_COMMAND_535, HART_COMMAND_539, HART_COMMAND_540}; return is_in_array(cmd, ARRAY_LEN(cmd), command); } // 判断版本是否支持当前指令 BOOL hart_is_support_command(uint16_t command, BOOL private_command) { if (HART_PROTOCOL_VERSION_SUPPORT_COMMAND == 0) { return TRUE; } // 先判断是否在用户自定义的指令中 uint16_t user_version[] = {/* HART_COMMAND_109, */ HART_COMMAND_129, HART_COMMAND_130, HART_COMMAND_131, HART_COMMAND_132, HART_COMMAND_133, HART_COMMAND_134, HART_COMMAND_135, HART_COMMAND_136, HART_COMMAND_138, HART_COMMAND_140, HART_COMMAND_141, HART_COMMAND_142, HART_COMMAND_143, HART_COMMAND_144, HART_COMMAND_145, HART_COMMAND_146, HART_COMMAND_147, HART_COMMAND_149, HART_COMMAND_150, HART_COMMAND_151, HART_COMMAND_153, HART_COMMAND_154, HART_COMMAND_155, HART_COMMAND_156, HART_COMMAND_157, HART_COMMAND_158, HART_COMMAND_162, HART_COMMAND_164, HART_COMMAND_165, HART_COMMAND_167, HART_COMMAND_168, HART_COMMAND_170, HART_COMMAND_187, HART_COMMAND_200}; if (is_in_array(user_version, ARRAY_LEN(user_version), command)) { return TRUE; } if (private_command == TRUE) { uint16_t lager_command[] = {HART_COMMAND_31, HART_COMMAND_523, HART_COMMAND_524}; if (is_in_array(lager_command, ARRAY_LEN(lager_command), command)) { return TRUE; } } if (hart_get_current_protocol_version() == HART_PROTOCOL_VERSION_5) { uint16_t version[] = {HART_COMMAND_0, HART_COMMAND_1, HART_COMMAND_2, HART_COMMAND_6, HART_COMMAND_11, HART_COMMAND_12, HART_COMMAND_13, HART_COMMAND_14, HART_COMMAND_15, HART_COMMAND_16, HART_COMMAND_17, HART_COMMAND_18, HART_COMMAND_19, HART_COMMAND_33, HART_COMMAND_34, HART_COMMAND_35, HART_COMMAND_36, HART_COMMAND_37, HART_COMMAND_38, HART_COMMAND_39, HART_COMMAND_40, HART_COMMAND_41, HART_COMMAND_42, HART_COMMAND_43, HART_COMMAND_44, HART_COMMAND_45, HART_COMMAND_46, HART_COMMAND_47, HART_COMMAND_48, HART_COMMAND_49, HART_COMMAND_50, HART_COMMAND_51, HART_COMMAND_52, HART_COMMAND_53, HART_COMMAND_54, HART_COMMAND_55, HART_COMMAND_56, HART_COMMAND_57, HART_COMMAND_58, HART_COMMAND_59, HART_COMMAND_60, HART_COMMAND_61, HART_COMMAND_62, HART_COMMAND_63, HART_COMMAND_64, HART_COMMAND_65, HART_COMMAND_66, HART_COMMAND_67, HART_COMMAND_68, HART_COMMAND_69, HART_COMMAND_70, HART_COMMAND_107, HART_COMMAND_109, HART_COMMAND_110}; if (is_in_array(version, ARRAY_LEN(version), command)) { return TRUE; } } if (hart_get_current_protocol_version() == HART_PROTOCOL_VERSION_7) { uint16_t version[] = {/*Universal Command */ HART_COMMAND_0, HART_COMMAND_1, HART_COMMAND_2, HART_COMMAND_3, HART_COMMAND_6, HART_COMMAND_7, HART_COMMAND_8, HART_COMMAND_9, HART_COMMAND_11, HART_COMMAND_12, HART_COMMAND_13, HART_COMMAND_14, HART_COMMAND_15, HART_COMMAND_16, HART_COMMAND_17, HART_COMMAND_18, HART_COMMAND_19, HART_COMMAND_20, HART_COMMAND_21, HART_COMMAND_22, HART_COMMAND_38, HART_COMMAND_48, /*Common Command */ HART_COMMAND_33, HART_COMMAND_35, HART_COMMAND_44, HART_COMMAND_50, HART_COMMAND_51, HART_COMMAND_52, HART_COMMAND_53, HART_COMMAND_54, HART_COMMAND_59}; if (is_in_array(version, ARRAY_LEN(version), command)) { return TRUE; } } LOG_ERR("command %d is not support", command); return FALSE; } /** * @brief 检查数据长度是否符合规定 * @param {uint8_t} data_length * @param {uint8_t} data_structure_length 原始的数据结构长度 * @return {*} * @note */ BOOL hart_frame_data_length_check(uint8_t data_length, uint8_t data_structure_length, uint8_t *resp_code) { if (data_length != data_structure_length) { if (data_length < data_structure_length) { *resp_code = RESPONSE_COMMUNICATION_CODE_5; return FALSE; } else { *resp_code = RESPONSE_COMMUNICATION_CODE_3; return FALSE; } } else { return TRUE; } } // 日期检测,年月日 BOOL check_date(rtc_date_t *date) { if (date->year > 99) { return FALSE; } if (date->month < 1 || date->month > 12) { return FALSE; } if (date->day < 1 || date->day > 31) { return FALSE; } return TRUE; } // 判断是否是广播地址 BOOL is_broadcast_address(uint8_t *address, uint8_t len) { for (uint8_t i = 0; i < len; i++) { if (*(address + i) != 0x00) { return FALSE; } } return TRUE; } // uint32转小时:分钟:秒:毫秒 void timestamp_to_hmsms(uint32_t timestamp, uint8_t *hmsms) { uint32_t ms = timestamp % 1000; uint32_t s = timestamp / 1000; uint32_t m = s / 60; uint32_t h = m / 60; hmsms[0] = h; hmsms[1] = m % 60; hmsms[2] = s % 60; hmsms[3] = ms; } // assic转十六进制(assic-6) void encode_ascii_6(const uint8_t *input, uint16_t input_length, uint8_t *output) { uint8_t adjusted_input[input_length]; uint16_t i = 0; osel_memset(adjusted_input, 0, input_length); for (i = 0; i < input_length; i++) { if (input[i] == 0x00) { adjusted_input[i] = 0x20; continue; } adjusted_input[i] = input[i] >= 0x40 ? input[i] - 0x40 : input[i]; } uint16_t acs8_len = i + 1; uint16_t acs6_len = acs8_len * 6 / 8; for (i = 0; i < acs6_len; i++) { uint8_t pos = i * 8 / 6; uint8_t val = adjusted_input[pos] & 0x3f; uint8_t valNext = pos + 1 < acs8_len ? (adjusted_input[pos + 1] & 0x3f) : 0x20; uint8_t newVal = 0; switch (i % 3) { case 0: newVal = val << 2; newVal += valNext >> 4; break; case 1: newVal = val << 4; newVal += valNext >> 2; break; case 2: newVal = val << 6; newVal += valNext; break; } output[i] = newVal; } } // assic-6 转 assic的十六进制 void decode_ascii_6(const uint8_t *input, uint16_t input_length, uint8_t *output) { uint16_t acs8_len = input_length * 8 / 6; for (uint16_t i = 0; i < acs8_len; i++) { uint8_t pos = i * 6 / 8; uint8_t val = input[pos]; uint8_t valNext = pos + 1 < input_length ? input[pos + 1] : 0; uint8_t newVal = 0; switch (i % 4) { case 0: newVal = (val & 0xfc) >> 2; break; case 1: newVal = (val & 3) << 4; newVal += (valNext & 240) >> 4; break; case 2: newVal = (val & 15) << 2; newVal += (valNext & 192) >> 6; break; case 3: newVal = val & 0x3f; break; } if (newVal < 0x20) newVal += 64; if (newVal == 0x20) newVal = 0; output[i] = newVal; } } // Time由一个无符号的32位二进制整数组成,最低有效位表示1/32毫秒(即0.03125毫秒)。 void convert_time(uint32_t t, uint8_t *h, uint8_t *m, uint8_t *s) { t = (t / 32); t = t / 1000; *h = t / 3600; *m = (t - (*h) * 3600) / 60; *s = t - (*h) * 3600 - (*m) * 60; } // Time由一个无符号的32位二进制整数组成,最低有效位表示1/32毫秒(即0.03125毫秒)。 void convert_timestrap(uint32_t *t, uint8_t h, uint8_t m, uint8_t s, uint16_t ms) { *t = (h * 3600 + m * 60 + s) * 1000 + ms; *t = (*t) * 32; } // 年份转换,HART的年份是从1900年开始的,如果要转换到标准的年份,需要加上1900。另外,HART的年份是一个字节,所以最大只能表示到2155年。 void covert_year_rtc(uint8_t *year) { uint8_t y = *year; *year = y - 100; } // 将RTC的年份转换为HART的年份 void covert_rtc_year(uint8_t *year) { uint8_t y = *year; *year = y + 100; } // 将RTC的年份转换成标准的年份 void covert_rtc_year_to_standard(uint16_t *year) { uint16_t y = *year; *year = y + 2000; } float32 covert_float(user_param_type_e data_type, void *data_p) { float32 f = 0; switch (data_type) { case USER_BYTE: f = *(uint8_t *)data_p; break; case USER_WORD: f = *(uint16_t *)data_p; break; case USER_UINT32: f = *(uint32_t *)data_p; break; case USER_FLOAT: f = *(float32 *)data_p; break; default: break; } return f; }