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/hart/hart_frame.c

388 lines
13 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.

/*
* @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)
{
if (HART_PROTOCOL_VERSION_SUPPORT_COMMAND == 0)
{
return TRUE;
}
// 先判断是否在用户自定义的指令中
uint16_t user_version[] = {/*HART_COMMAND_31, 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 (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;
}