/****************************************************************************** 版权所有: 文件名称: equ.c 文件版本: 01.01 创建作者: sunxi 创建日期: 2013-03-25 功能说明: 装置信息管理维护 其它说明: 修改记录: */ /*------------------------------- 头文件 -------------------------------------- */ #include "head.h" /*------------------------------- 宏定义 -------------------------------------- */ #define EQU_SLOT_CHECK_TIMEOUT 4 // 子板检查超时,以秒为单位,不能小于4s /*------------------------------ 类型结构 ------------------------------------- */ //子板信息帧结构 struct board_info_frame { u8 type; // 子板类型 u8 status :4; // 子板状态 u8 errcode:4; // 子板错误代码 u16 crc; // 子板CRC u32 version; // 子板版本 }; /*------------------------------ 全局变量 ------------------------------------- */ // 控制板类型 u32 g_brd_type_kz; // 采样板索引和插槽的对应关系 const int g_ac_index_to_slot[EQU_SLOT_AC_NUM] = {1}; // 采样板起始槽位,每种机箱不一样。 u32 g_ac_slot_begin; // 记录频率对应ui通道的索引值 int g_ui_freq[CFG_FREQ_NUM]; // 模拟量对应关系 static const s8 g_ac_index[BOARD_TYPE_KZ_NUM][EQU_SLOT_AC_CHN] = { {0X01, 0X03, 0X05, 0X07, 0XFF, 0XFF, 0XFF, 0XFF, 0X00, 0X02, 0X04, 0X06, 0X0E, 0X0C, 0X0A, 0X08}, // 24款分布式 lch }; //遥信转换表 s8 g_change_di_index[BOARD_TYPE_KZ_NUM][EQU_DB_YX_NUM] = { {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}, }; // 开出对应关系 static const s8 g_do_index[BOARD_TYPE_KZ_NUM][DO_NUM] = { {-1,-1,-1,-1-1,-1,-1,-1-1,-1,-1,-1}, }; /*------------------------------ 函数声明 ------------------------------------- */ unsigned int change_di_ch(unsigned int di) { register int i, rts = 0; #if 0 static int di_bak; if(di_bak!=di) { rt_printf_time("change_di_ch di=%x \r\n",di); di_bak=di; } #endif for (i = 0; i < EQU_DB_YX_NUM; i++) { if (g_change_di_index[g_brd_type_kz][i] != 0 && g_change_di_index[g_brd_type_kz][i] <= EQU_DB_YX_NUM) { if (di >> (g_change_di_index[g_brd_type_kz][i] - 1) & 0x01) rts |= (1 << i); } } // rt_printf("%d %d 。。",rts,g_brd_type_kz); return rts; } /*------------------------------ 外部函数 ------------------------------------- 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性. */ /** * @brief 远动参数投入之后 遥信防抖时间的更新 * @return * int * @retval none * * @warning none * @note none */ int equ_config_di_yd(void) { u32 i; struct equ_config_di *ecd; // 用户配置的保持时间、拥有者、类型 ecd = g_equ_config_di; for (i = 0; i < g_equ_config->di_num; i++) { g_di_st[ecd->slot][ecd->index].tm_filter = (u32)tRunPara.wYXFD * 1000; ecd++; } return 0; } int equ_config_do_yd(void) { #if 0 int i,index; struct equ_config_do *ecd; // 用户配置的保持时间 ecd = g_equ_config_do; for(i=0;ido_num;i++) { u32 dotime=(u32)ecd->time_pulse; if(ecd->slot == EQU_SLOT_KZ) { // 如果定值参数中设置了分闸时间,覆盖 if(ecd->owner&&((ecd->type == (SW_DO_FZ+1))||(ecd->type == (SW_DO_BHT+1))||(ecd->type == (SW_DO_YKT+1)))) { if(pRunSet->bTT_RmtPara) { dotime=tRunPara.wFZMC; } } // 如果定值参数中设置了合闸时间,覆盖 if(ecd->owner&&((ecd->type == (SW_DO_HZ+1))||(ecd->type == (SW_DO_BHH+1))||(ecd->type == (SW_DO_YKH+1)))) { if(pRunSet->bTT_RmtPara) { dotime=tRunPara.wHZMC; } } index = equ_get_do_channel(ecd->index); g_do_st[index].us_keep = (u32)dotime; g_do_st[index].us_keep *= 1000; //ms转换为us } ecd++; } #endif return 0; } int equ_init_di(void) { int i,ui; struct equ_config_di *ecd; // 采样板起始槽位 g_ac_slot_begin = EQU_SLOT_AC_BEGIN; #if !defined CPU_FUXI /* 注意t536版fuxi不使用这个配置 */ // 检查频率硬件通道对应的UI。 g_ui_freq[0] = UI_NUM; g_ui_freq[1] = UI_NUM; for (i = 0; i < g_equ_config->ac_num; i++) { // 频率通道必须是配置了的公共电压类型 if (g_equ_config_ac[i].type == 0 || g_equ_config_ac[i].owner != 0) { continue; } ui = g_equ_config_ac[i].type - 1; if (ui >= PUB_AC_NUM) { continue; } // 确定频率对应电压通道 if (ui < PUB_AC_NUM) { if (g_equ_config_ac[i].slot == 9 && g_equ_config_ac[i].index == 0) { g_ui_freq[0] = ui; } if (g_equ_config_ac[i].slot == 10 && g_equ_config_ac[i].index == 0) { g_ui_freq[1] = ui; } } } #endif // 初始化开入g_di_st结构 memset((unsigned char *)g_di_st, 0, sizeof(g_di_st)); ecd = g_equ_config_di; for (i = 0; i < g_equ_config->di_num; i++) { g_di_st[ecd->slot][ecd->index].tm_filter = ecd->filter_time; g_di_st[ecd->slot][ecd->index].owner = ecd->owner; g_di_st[ecd->slot][ecd->index].type = ecd->type; ecd++; } // 找到配置为开入板的板卡号 for (i = 0; i < g_equ_config->equ_slot_num; i++) { if (g_board_info[i].type == BOARD_TYPE_FUXI_DI) { g_di_slot = i; break; } } // rt_printf("g_di_slot = %d\r\n", g_di_slot); return 0; } #ifdef BSP_CAN_ENABLE /****************************************************************************** 函数名称: equ_board_info_update 函数版本: 01.01 创建作者: sunxi 创建日期: 2013-08-08 函数说明: 接收到子板的对时应答帧后,更新子板信息 参数说明: can_bus 从哪条can总线接收到的帧。 frame 接收帧的buf指针 返回值: 0: 成功 其它: 失败 修改记录: */ int equ_board_info_update(int can_bus,u8 * frame) { struct can_frame_head *cfh; struct board_info_frame *bif; struct board_info *bi; // 检查帧内容 cfh = (struct can_frame_head *)frame; #ifdef CAN_SLAVE_BOARD if(cfh->src >= (EQU_SLOT_NUM_MAX+CAN_BOARD_NUM)) #else if(cfh->src >= EQU_SLOT_NUM_MAX) #endif { return -1; } if(cfh->len != 8) { return -2; } // 比较子板类型 bi = &g_board_info[cfh->src]; bif = (struct board_info_frame *)(frame + sizeof(cfh)); if(bif->type != bi->type) { // rt_printf("board type error(no=%d,bi_type=%d,gbi_type=%d)\r\n",cfh->src,bif->type,bi->type); // print_mem("frame",frame,16); return -3; } // 得到子板信息 bi->status = bif->status; bi->errcode = bif->errcode; bi->crc = bif->crc; bi->version = bif->version; //rt_printf("%02d\t%02d\t%02d\t%04x\t%08x\t",bi->type,bi->status,bi->errcode,bi->crc,bi->version); // 得到子板时间 clk_time_get(&bi->update_time); bi->us0 = ustimer_get_origin(); bi->is_ok = 1; bi->can_bus = can_bus; return 0; } #endif /****************************************************************************** 函数名称: equ_ac_channel_is_ok 函数版本: 01.01 创建作者: sunxi 创建日期: 2013-08-08 函数说明: 得到插槽中子板的模拟量通道对应的ADC采样通道。 参数说明: slot 插槽索引号 index 子板上模拟量通道索引号 返回值: ADC采样通道索引号 修改记录: */ int equ_ac_channel_is_ok(u32 index) { // 检查参数 if(index >= CFG_ADC_CHANNEL) { return 0; } // 直接返回ok 板卡没有配置检测io return 1; // return g_ac_slot_is_ok[index/EQU_SLOT_AC_CHN]; } /****************************************************************************** 函数名称: equ_get_ac_channel 函数版本: 01.01 创建作者: sunxi 创建日期: 2013-08-08 函数说明: 得到插槽中子板的模拟量通道对应的ADC采样通道。 参数说明: slot 插槽索引号 index 子板上模拟量通道索引号 返回值: ADC采样通道索引号 修改记录: */ int equ_get_ac_channel(u32 slot,u32 index) { // 检查参数 #if (0) /* 不检查 插槽索引号 lch 2025年12月5日17:29:28 */ if(slot != BOARD_TYPE_FUXI_AC) { return -1; } #endif if(index >= CFG_ADC_CHANNEL) { return -2; } return g_ac_index[g_brd_type_kz][index]; } /****************************************************************************** 函数名称: equ_get_ac_slot 函数版本: 01.01 创建作者: xxxxxx 创建日期: 2014-10-09 函数说明: 得到采样通道对应的板卡 参数说明: owner 归属公共、开关 type 采样类型 返回值: ADC采样通道索引号 修改记录: */ int equ_get_ac_slot(u32 owner, u32 type) { u32 no; if (owner) { no = g_sw[owner].ac_cfg_index[type]; } else { no = g_sw_pub.ac_cfg_index[type]; } return g_equ_config_ac[no].slot; } /****************************************************************************** 函数名称: equ_ac_index_to_slot 函数版本: 01.01 创建作者: sunxi 创建日期: 2013-08-08 函数说明: 将采样板索引号(和ADC通道号对应)转换为插槽号。 参数说明: ac_index 采样板索引号 返回值: 插槽号 修改记录: */ int equ_ac_index_to_slot(int ac_index) { if((u32)ac_index >= EQU_SLOT_AC_NUM) { return 0; } return g_ac_index_to_slot[ac_index]; } /****************************************************************************** 函数名称: equ_get_do_channel 函数版本: 01.01 创建作者: sunxi 创建日期: 2013-08-08 函数说明: 配置子板上的开出资源 参数说明: slot 插槽索引号 返回值: 插槽号 0: 成功 其它: 失败 修改记录: */ int equ_get_do_channel(u32 index) { return g_do_index[g_brd_type_kz][index]; } #ifdef CPU_FUXI /** * @brief 初始化rv核数据 * @author lch (lch_work@foxmail.com) * @version 1.0 * @date 20251222 * @return * int * @retval none * * @warning none * @note none */ int equ_init_rv_di(void) { struct t_shmdata_di_astime t_di_cfg = {0}; struct equ_config_di *ecd; ecd = g_equ_config_di; // rt_printf("g_equ_config->di_num = %d\r\n", g_equ_config->di_num); for (int i = 0; i < g_equ_config->di_num; i++) { t_di_cfg.us_as_time[i] = ecd->filter_time; ecd++; } return shm_packet_write_v2(SHM_ADDR_R_DI_ASTIME, (uint8_t *)&t_di_cfg, sizeof(struct t_shmdata_di_astime)); } /** * @brief 初始化rv核数据 * @author lch (lch_work@foxmail.com) * @version 1.0 * @date 20251222 * @return * int * @retval none * * @warning none * @note none */ int equ_reinit_rv_di(void) { struct t_shmdata_di_astime t_di_cfg = {0}; for (int i = 0; i < g_equ_config->di_num; i++) { t_di_cfg.us_as_time[i] = tRunPara.wYXFD; } return shm_packet_write_v2(SHM_ADDR_R_DI_ASTIME, (uint8_t *)&t_di_cfg, sizeof(struct t_shmdata_di_astime)); } #endif /*------------------------------ 内部函数 ------------------------------------- 内部函数以下划线‘_’开头,不需要检查参数的合法性. */ /*------------------------------ 测试函数 ------------------------------------- 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数). */ /*------------------------------ 文件结束 ------------------------------------- */