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.c

451 lines
12 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:00
* @LastEditors: xxx
* @LastEditTime: 2023-08-29 11:44:01
* @FilePath: \hart\hart\hart.c
* @Description: hart模块接口
* email:
* Copyright (c) 2023 by xxx, All Rights Reserved.
*/
#include "./inc/hart.h"
#include "./slave/inc/hart_slave_frame.h"
#define HART_INIT_FLAG (0x0520) ///< 初始化标志
static hart_init_t handle;
static hart_response_t response;
BOOL(*hart_command_ptr_arr[HART_COMMAND_MAX])
(const hart_command_req_t *const req, hart_response_t *resp);
/**
* @brief 获取HART句柄
*
* 该函数返回HART句柄的指针。
*
* @return 返回HART句柄的指针
*/
hart_init_t *hart_get_handle(void)
{
return &handle;
}
/**
* @brief hart模块初始化
* @param {hart_init_t} *init: 初始化参数
* @return: TRUE: 初始化成功
* FALSE: 初始化失败
*/
BOOL hart_init(const hart_init_t *const init)
{
// 将初始数据赋值给handle
if (!DBG_ASSERT(init != NULL __DBG_LINE))
return FALSE;
osel_memcpy((uint8_t *)&handle, (uint8_t *)init, sizeof(hart_init_t));
// 检查参数
if (!DBG_ASSERT((handle.dir == MODULE_MASTER) || (handle.dir == MODULE_SLAVE) __DBG_LINE))
return FALSE;
if (!DBG_ASSERT(handle.interface.response != NULL __DBG_LINE))
return FALSE;
// 缓存消息初始化
hart_cache_init();
#ifdef MASTER
if (handle.dir == MODULE_MASTER) // 主机模块初始化
{
handle.hart_module_u._master.address_bit = handle.master_address_bit;
if (handle.hart_module_u._master.address_bit != HART_MASTER)
{
handle.hart_module_u._master.address_bit = 0;
}
handle.hart_module_u._master.response_call = handle.interface.response;
handle.hart_module_u._master.response = &response;
if (!DBG_ASSERT(hart_master_init(&handle.hart_module_u._master) == TRUE __DBG_LINE))
return FALSE;
#if MOCK == 1
mock_master_attribute();
#endif
}
#endif
#ifdef SLAVE
hart_device_attribute.hart_protocol_version = &handle.hart_protocol_version;
hart_device_attribute.message_count.phack = 0; // 响应消息计数
hart_device_attribute.message_count.shack = 0; // 响应消息计数
if (!DBG_ASSERT((hart_get_current_protocol_version() == HART_PROTOCOL_VERSION_5 ||
hart_get_current_protocol_version() == HART_PROTOCOL_VERSION_7) __DBG_LINE)) // 校验协议版本号模块支持协议版本为5,7
return FALSE;
if (handle.dir == MODULE_SLAVE) // 从机模块初始化
{
#ifdef STM32
if (!DBG_ASSERT(handle.interface.flash_read != NULL __DBG_LINE)) // 从机模块必须实现flash_read接口
return FALSE;
if (!DBG_ASSERT(handle.interface.flash_write != NULL __DBG_LINE)) // 从机模块必须实现flash_write接口
return FALSE;
if (!DBG_ASSERT(handle.interface.flash_read_item != NULL __DBG_LINE)) // 从机模块必须实现flash_read接口
return FALSE;
if (!DBG_ASSERT(handle.interface.flash_write_item != NULL __DBG_LINE)) // 从机模块必须实现flash_write接口
return FALSE;
if (!DBG_ASSERT(handle.interface.perform_self_test != NULL __DBG_LINE)) // 从机模块必须实现perform_self_test接口
return FALSE;
if (!DBG_ASSERT(handle.interface.device_reset != NULL __DBG_LINE)) // 从机模块必须实现device_reset接口
return FALSE;
if (!DBG_ASSERT(handle.interface.squawk_control != NULL __DBG_LINE)) // 从机模块必须实现squawk_control接口
return FALSE;
if (!DBG_ASSERT(handle.interface.armed != NULL __DBG_LINE)) // 从机模块必须实现armed接口
return FALSE;
if (!DBG_ASSERT(handle.interface.user_common_event != NULL __DBG_LINE)) // 从机模块必须实现user_common_event接口
return FALSE;
#endif
handle.hart_module_u._slave.response_call = handle.interface.response;
handle.hart_module_u._slave.response = &response;
if (!DBG_ASSERT(hart_slave_init(&handle.hart_module_u._slave) == TRUE __DBG_LINE))
return FALSE;
#ifdef STM32
hart_slave_device_attribute_init();
if (!DBG_ASSERT(handle.interface.set_dynamics != NULL __DBG_LINE)) // 从机模块必须动态数据接口
return FALSE;
BOOL ret = FALSE;
BOOL ret2 = FALSE;
BOOL ret3 = FALSE;
// 从flash中读取设备属性
ret = handle.interface.flash_read(HART_STORAGE_PARAMS, (uint8_t *)&hart_device_attribute.flash_variable);
if (ret == TRUE)
{
if (hart_device_attribute.flash_variable.init_flag != HART_INIT_FLAG)
{
ret = FALSE;
}
}
if (ret == FALSE)
{
INIT:
if (!DBG_ASSERT(handle.interface.attribute_init != NULL __DBG_LINE))
return FALSE;
handle.interface.attribute_init();
handle.interface.variable_init();
}
else
{
ret = handle.interface.flash_read(HART_STORAGE_VARIABLE, (uint8_t *)&hart_device_attribute.device_variable);
if (ret == TRUE)
{
ret2 = handle.interface.flash_read(HART_STORAGE_CONSTANT, (uint8_t *)&hart_device_attribute.device_constant);
}
if (ret2 == TRUE)
{
ret3 = handle.interface.flash_read(HART_STORAGE_STANDARD_VARIABLE, (uint8_t *)&hart_device_attribute.device_standard_variable);
}
// 注hart_device_attribute.device_variable[0].code != DIN_ANALOG_INPUT 这个判断是为了解决没有读到数据的情况flash_variable可以设置crc32,这个变量是数组无法设定,用第一个和第二个变量判断
if (ret == FALSE || ret2 == FALSE || ret3 == FALSE ||
hart_device_attribute.device_variable[0].code != DIN_ANALOG_INPUT || hart_device_attribute.device_variable[1].code != DIN_INTERNAL_TEMPERATURE)
{
goto INIT;
}
}
// 动态属性
handle.interface.set_dynamics(&hart_device_attribute.dynamics);
hart_device_attribute.hart_protocol_version = &handle.hart_protocol_version;
hart_device_attribute.message_count.phack = 0; // 响应消息计数
hart_device_attribute.message_count.shack = 0; // 响应消息计数
#else
mock_data();
#endif
}
#endif
return TRUE;
}
/**
* @brief hart模块数据处理函数
* @param {uint8_t} uart_index: 串口索引
* @param {uint8_t} uart_error: 串口错误
* @param {uint8_t} *rxBuf: 接收到的数据
* @param {uint16_t} len: 接收到的数据长度
* @return: TRUE: 处理成功
* FALSE: 处理失败
*/
BOOL hart_handle(uint8_t uart_index, uint8_t *rxBuf, uint16_t len)
{
if (!DBG_ASSERT(rxBuf != NULL __DBG_LINE))
return FALSE;
if (!DBG_ASSERT(len != 0 __DBG_LINE))
return FALSE;
if (!DBG_ASSERT((handle.dir == MODULE_MASTER) || (handle.dir == MODULE_SLAVE) __DBG_LINE))
return FALSE;
// 根据模块工作模式将数据分发给对应的主机或从机处理
#ifdef MASTER
if (handle.dir == MODULE_MASTER)
{
return hart_master_handle(rxBuf, len);
}
#endif
#ifdef SLAVE
if (handle.dir == MODULE_SLAVE)
{
return hart_slave_handle(uart_index, rxBuf, len);
}
#endif
return FALSE;
}
void hart_cache_data_send(uint64_t uuid)
{
hart_cache_t *p;
p = hart_cache_get(uuid);
if (NULL != p)
{
LOG_PRINT("%d", p->uuid);
#ifdef SLAVE
hart_slave_device_send(p);
#endif
}
}
/**
* @brief 获取指定UART接口的错误计数
*
* 该函数用于获取指定UART接口的错误计数。
*
* @param uart_index UART接口的索引
*
* @return 返回指定UART接口的错误计数
*/
uint16_t hart_uart_error_count(uint8_t uart_index)
{
return handle.interface.uart_error_count(uart_index);
}
/**
* @brief 处理UART错误
*
* 该函数用于处理指定UART接口的错误。
*
* @param uart_index UART接口的索引
* @param errors 用于存储错误信息的指针
*/
void hart_uart_errors(uint8_t uart_index, hart_uart_error_t *errors)
{
handle.interface.uart_errors(uart_index, errors);
}
/**
* @brief 开始解析帧数据的计时
*
* 该函数用于启动帧数据解析的计时器。
*
* @param timer_period 计时器周期
*/
void frame_data_parse_time_start(uint16_t timer_period)
{
handle.interface.frame_data_parse_time_start(timer_period);
}
/**
* @brief 获取时间戳
* @return {*}
* @note
*/
uint32_t hart_get_timestamp(void)
{
return handle.interface.get_timestamp();
}
/**
* @brief flash写入 hart内部使用
* @param {uint32_t} addr
* @param {uint8_t} *data
* @return {*}
*/
BOOL hart_storage_write(hart_storage_e index, uint8_t *data)
{
return handle.interface.flash_write(index, data);
}
/**
* @brief falsh读取 hart内部使用
* @param {uint32_t} addr
* @param {uint8_t} *dat
* @return {*}
*/
BOOL hart_storage_read(hart_storage_e index, uint8_t *data)
{
return handle.interface.flash_read(index, data);
}
BOOL hart_storage_write_item(hart_storage_e index, uint8_t item, uint8_t *data)
{
return handle.interface.flash_write_item(index, item, data);
}
BOOL hart_storage_read_item(hart_storage_e index, uint8_t item, uint8_t *data)
{
return handle.interface.flash_read_item(index, item, data);
}
/**
* @brief 自检
* @return {*}
*/
void hart_perform_self_test(void)
{
#ifdef SLAVE
hart_device_attribute.device_status.busy = TRUE;
handle.interface.perform_self_test();
#endif
}
/**
* @brief 自检完成
* @return {*}
*/
void perform_self_test_finish(void)
{
#ifdef SLAVE
hart_device_attribute.device_status.busy = FALSE;
#endif
}
/**
* @brief 设备复位
* @return {*}
*/
void hart_device_reset(void)
{
hart_device_attribute.device_status.reset = TRUE;
handle.interface.device_reset(); // 这里的接口不是真复位而是在LCD上显示复位信息
}
/**
* @brief 呼叫
* @param {BOOL} open
* @param {uint8_t} second
* @return {*}
*/
void hart_squawk_control(BOOL open, uint8_t second)
{
handle.interface.squawk_control(open, second);
}
/**
* @brief 技术人员按下一个特殊的按钮或按钮组合指示从机应响应command74
* @return {*}
*/
BOOL hart_armed(void)
{
return handle.interface.armed();
}
/**
* @brief 设置实时时钟
* @param {uint8_t} year
* @param {uint8_t} month
* @param {uint8_t} day
* @param {uint8_t} hour
* @param {uint8_t} min
* @param {uint8_t} sec
* @return {*}
* @note
*/
void hart_set_real_time_clock(uint8_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec)
{
if (handle.interface.set_real_time_clock == NULL)
return;
handle.interface.set_real_time_clock(year, month, day, hour, min, sec);
}
/**
* @brief 获取实时时钟
* @param {uint8_t} *year
* @param {uint8_t} *month
* @param {uint8_t} *day
* @param {uint8_t} *hour
* @param {uint8_t} *min
* @param {uint8_t} *sec
* @return {*}
* @note
*/
void hart_get_real_time_clock(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *hour, uint8_t *min, uint8_t *sec)
{
if (handle.interface.get_real_time_clock == NULL)
return;
handle.interface.get_real_time_clock(year, month, day, hour, min, sec);
}
BOOL hart_user_common_event(hart_interface_user_event_e event, const void *const data)
{
#ifdef STM32
if (handle.interface.user_common_event == NULL)
return FALSE;
return handle.interface.user_common_event(event, data);
#else
return TRUE;
#endif
}
BOOL get_device_lock(void)
{
return hart_device_attribute.flash_variable.lock_code == LOCK_DEVICE_CODE_0 ? FALSE : TRUE;
}
/**
* @brief 定时器中断回调函数
*
* 当定时器触发中断时,该函数会被调用。
* 该函数为空实现,用户可以根据具体需求进行扩展。
*/
void hart_timer_interupt_cb(void)
{
if (hart_get_handle()->hart_timer.counter > 0)
{
hart_get_handle()->hart_timer.counter--;
}
}
/**
* @brief 启动HART定时器
*
* 设置HART定时器的周期并启动定时器。
*
* @param timer_period 定时器周期(单位:毫秒)
*/
void hart_timer_start(uint16_t timer_period)
{
hart_get_handle()->hart_timer.counter = timer_period / hart_get_handle()->hart_timer.timer_cycle;
}
/**
* 1. 每个字节间隔超过10毫秒就丢弃这组数据
* 2. 数据处理的时间257毫秒丢包
*/
BOOL hart_timeout_compare(void)
{
if (hart_get_handle()->hart_timer.counter == 0)
{
return FALSE;
}
else
{
return TRUE;
}
}